]> granicus.if.org Git - clang/commitdiff
[analyzer] C++ initializers may require cleanups; look through these.
authorJordan Rose <jordan_rose@apple.com>
Sat, 26 Jan 2013 03:16:31 +0000 (03:16 +0000)
committerJordan Rose <jordan_rose@apple.com>
Sat, 26 Jan 2013 03:16:31 +0000 (03:16 +0000)
When the analyzer sees an initializer, it checks if the initializer
contains a CXXConstructExpr. If so, it trusts that the CXXConstructExpr
does the necessary work to initialize the object, and performs no further
initialization.

This patch looks through any implicit wrapping expressions like
ExprWithCleanups to find the CXXConstructExpr inside.

Fixes PR15070.

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

lib/StaticAnalyzer/Core/ExprEngine.cpp
test/Analysis/initializer.cpp

index a1fc29eb7e40af487ea67ff7251a21500bd9c8ff..26a3f9b1f5307953ed9e3a76f729cf80780cfd59 100644 (file)
@@ -404,7 +404,7 @@ void ExprEngine::ProcessInitializer(const CFGInitializer Init,
   if (BMI->isAnyMemberInitializer()) {
     // Constructors build the object directly in the field,
     // but non-objects must be copied in from the initializer.
-    const Expr *Init = BMI->getInit();
+    const Expr *Init = BMI->getInit()->IgnoreImplicit();
     if (!isa<CXXConstructExpr>(Init)) {
       SVal FieldLoc;
       if (BMI->isIndirectMemberInitializer())
index d4f336977e31eb07159a8948c5993089bda9615e..ab2eb90143670fdc374410bcf6cd6a8e58046510 100644 (file)
@@ -80,3 +80,33 @@ class StringWrapper {
 public:
   StringWrapper(const char *input) : str(strdup(input)) {} // no-warning
 };
+
+
+// PR15070 - Constructing a type containing a non-POD array mistakenly
+// tried to perform a bind instead of relying on the CXXConstructExpr,
+// which caused a cast<> failure in RegionStore.
+namespace DefaultConstructorWithCleanups {
+  class Element {
+  public:
+    int value;
+
+    class Helper {
+    public:
+      ~Helper();
+    };
+    Element(Helper h = Helper());
+  };
+  class Wrapper {
+  public:
+    Element arr[2];
+
+    Wrapper();
+  };
+
+  Wrapper::Wrapper() /* initializers synthesized */ {}
+
+  int test() {
+    Wrapper w;
+    return w.arr[0].value; // no-warning
+  }
+}