]> granicus.if.org Git - clang/commitdiff
[analyzer] Inline ctors + dtors when the CFG is built for them.
authorJordan Rose <jordan_rose@apple.com>
Thu, 26 Jul 2012 20:04:00 +0000 (20:04 +0000)
committerJordan Rose <jordan_rose@apple.com>
Thu, 26 Jul 2012 20:04:00 +0000 (20:04 +0000)
At the very least this means initializer nodes for constructors and
automatic object destructors are present in the CFG.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@160803 91177308-0d34-0410-b5e6-96231b3b80d8

lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
test/Analysis/dtor.cpp

index 62c288dad4b00f839e309fb165a4e443ef3fc663..4431c03d497e1f29229ccbbf77cba5b1d6c19f0d 100644 (file)
@@ -286,10 +286,15 @@ bool ExprEngine::inlineCall(const CallEvent &Call,
     // These are always at least possible to inline.
     break;
   case CE_CXXConstructor:
-  case CE_CXXDestructor:
-    // Do not inline constructors until we can really model destructors.
-    // This is unfortunate, but basically necessary for smart pointers and such.
-    return false;
+  case CE_CXXDestructor: {
+    // Only inline constructors and destructors if we built the CFGs for them
+    // properly.
+    const AnalysisDeclContext *ADC = CallerSFC->getAnalysisDeclContext();
+    if (!ADC->getCFGBuildOptions().AddImplicitDtors ||
+        !ADC->getCFGBuildOptions().AddInitializers)
+      return false;
+    break;
+  }
   case CE_CXXAllocator:
     // Do not inline allocators until we model deallocators.
     // This is unfortunate, but basically necessary for smart pointers and such.
index 8d63cc47bed42525fcbfa15d3640c06ea14a7c10..5a14f3025d43142c6ebce51e05ef94b9bf45379a 100644 (file)
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-store region -analyzer-ipa=inlining -cfg-add-implicit-dtors -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc -analyzer-store region -analyzer-ipa=inlining -cfg-add-implicit-dtors -cfg-add-initializers -verify %s
 
 class A {
 public:
@@ -11,3 +11,26 @@ public:
 int main() {
   A a;
 }
+
+
+typedef __typeof(sizeof(int)) size_t;
+void *malloc(size_t);
+void free(void *);
+
+class SmartPointer {
+  void *X;
+public:
+  SmartPointer(void *x) : X(x) {}
+  ~SmartPointer() {
+    free(X);
+  }
+};
+
+void testSmartPointer() {
+  char *mem = (char*)malloc(4);
+  {
+    SmartPointer Deleter(mem);
+    // destructor called here
+  }
+  *mem = 0; // expected-warning{{Use of memory after it is freed}}
+}