george.karpenkov created this revision.
Herald added subscribers: szepet, xazax.hun, javed.absar.

Fixes https://bugs.llvm.org/show_bug.cgi?id=30565

@dcoughlin Any advice on how to handle different stdlib implementations?
Can we conjure a separate symbol instead of relying on a particular struct 
layout?
For now this implementation will simply not go inside a differently implemented 
`call_once`.


https://reviews.llvm.org/D38702

Files:
  lib/Analysis/BodyFarm.cpp
  test/Analysis/call_once.cpp


Index: test/Analysis/call_once.cpp
===================================================================
--- test/Analysis/call_once.cpp
+++ test/Analysis/call_once.cpp
@@ -231,3 +231,12 @@
   int x = call_once();
   clang_analyzer_eval(x == 5); // expected-warning{{TRUE}}
 }
+
+namespace std {
+template <typename d, typename e>
+void call_once(d, e);
+}
+void g();
+void test_no_segfault_on_different_impl() {
+  std::call_once(g, false); // no-warning
+}
Index: lib/Analysis/BodyFarm.cpp
===================================================================
--- lib/Analysis/BodyFarm.cpp
+++ lib/Analysis/BodyFarm.cpp
@@ -362,6 +362,12 @@
                         /* GetNonReferenceType=*/true);
 
   CXXRecordDecl *FlagCXXDecl = FlagType->getAsCXXRecordDecl();
+  if (FlagCXXDecl == nullptr) {
+    DEBUG(llvm::dbgs() << "Flag field is not a CXX record: "
+                       << "unknown std::call_once implementation."
+                       << "Ignoring the call.\n");
+    return nullptr;
+  }
 
   // Note: here we are assuming libc++ implementation of call_once,
   // which has a struct with a field `__state_`.


Index: test/Analysis/call_once.cpp
===================================================================
--- test/Analysis/call_once.cpp
+++ test/Analysis/call_once.cpp
@@ -231,3 +231,12 @@
   int x = call_once();
   clang_analyzer_eval(x == 5); // expected-warning{{TRUE}}
 }
+
+namespace std {
+template <typename d, typename e>
+void call_once(d, e);
+}
+void g();
+void test_no_segfault_on_different_impl() {
+  std::call_once(g, false); // no-warning
+}
Index: lib/Analysis/BodyFarm.cpp
===================================================================
--- lib/Analysis/BodyFarm.cpp
+++ lib/Analysis/BodyFarm.cpp
@@ -362,6 +362,12 @@
                         /* GetNonReferenceType=*/true);
 
   CXXRecordDecl *FlagCXXDecl = FlagType->getAsCXXRecordDecl();
+  if (FlagCXXDecl == nullptr) {
+    DEBUG(llvm::dbgs() << "Flag field is not a CXX record: "
+                       << "unknown std::call_once implementation."
+                       << "Ignoring the call.\n");
+    return nullptr;
+  }
 
   // Note: here we are assuming libc++ implementation of call_once,
   // which has a struct with a field `__state_`.
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to