[cfe-commits] r160810 - in /cfe/trunk: lib/Analysis/AnalysisDeclContext.cpp lib/StaticAnalyzer/Core/PathDiagnostic.cpp test/Analysis/ctor-inlining.mm test/Analysis/dtor.cpp

Jordan Rose jordan_rose at apple.com
Thu Jul 26 13:04:30 PDT 2012


Author: jrose
Date: Thu Jul 26 15:04:30 2012
New Revision: 160810

URL: http://llvm.org/viewvc/llvm-project?rev=160810&view=rev
Log:
[analyzer] Don't crash on implicit statements inside initializers.

Our BugReporter knows how to deal with implicit statements: it looks in
the ParentMap until it finds a parent with a valid location. However, since
initializers are not in the body of a constructor, their sub-expressions are
not in the ParentMap. That was easy enough to fix in AnalysisDeclContext.

...and then even once THAT was fixed, there's still an extra funny case
of Objective-C object pointer fields under ARC, which are initialized with
a top-level ImplicitValueInitExpr. To catch these cases,
PathDiagnosticLocation will now fall back to the start of the current
function if it can't find any other valid SourceLocations. This isn't great,
but it's miles better than a crash.

(All of this is only relevant when constructors and destructors are being
inlined, i.e. under -cfg-add-initializers and -cfg-add-implicit-dtors.)

Added:
    cfe/trunk/test/Analysis/ctor-inlining.mm
Modified:
    cfe/trunk/lib/Analysis/AnalysisDeclContext.cpp
    cfe/trunk/lib/StaticAnalyzer/Core/PathDiagnostic.cpp
    cfe/trunk/test/Analysis/dtor.cpp

Modified: cfe/trunk/lib/Analysis/AnalysisDeclContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/AnalysisDeclContext.cpp?rev=160810&r1=160809&r2=160810&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/AnalysisDeclContext.cpp (original)
+++ cfe/trunk/lib/Analysis/AnalysisDeclContext.cpp Thu Jul 26 15:04:30 2012
@@ -181,8 +181,16 @@
 }
 
 ParentMap &AnalysisDeclContext::getParentMap() {
-  if (!PM)
+  if (!PM) {
     PM.reset(new ParentMap(getBody()));
+    if (const CXXConstructorDecl *C = dyn_cast<CXXConstructorDecl>(getDecl())) {
+      for (CXXConstructorDecl::init_const_iterator I = C->init_begin(),
+                                                   E = C->init_end();
+           I != E; ++I) {
+        PM->addStmt((*I)->getInit());
+      }
+    }
+  }
   return *PM;
 }
 

Modified: cfe/trunk/lib/StaticAnalyzer/Core/PathDiagnostic.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/PathDiagnostic.cpp?rev=160810&r1=160809&r2=160810&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/PathDiagnostic.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/PathDiagnostic.cpp Thu Jul 26 15:04:30 2012
@@ -253,16 +253,33 @@
   // source code, so find an enclosing statement and use its location.
   if (!L.isValid()) {
 
-    ParentMap *PM = 0;
+    AnalysisDeclContext *ADC;
     if (LAC.is<const LocationContext*>())
-      PM = &LAC.get<const LocationContext*>()->getParentMap();
+      ADC = LAC.get<const LocationContext*>()->getAnalysisDeclContext();
     else
-      PM = &LAC.get<AnalysisDeclContext*>()->getParentMap();
+      ADC = LAC.get<AnalysisDeclContext*>();
 
-    while (!L.isValid()) {
-      S = PM->getParent(S);
-      L = UseEnd ? S->getLocEnd() : S->getLocStart();
-    }
+    ParentMap &PM = ADC->getParentMap();
+
+    const Stmt *Parent = S;
+    do {
+      Parent = PM.getParent(Parent);
+
+      // In rare cases, we have implicit top-level expressions,
+      // such as arguments for implicit member initializers.
+      // In this case, fall back to the start of the body (even if we were
+      // asked for the statement end location).
+      if (!Parent) {
+        const Stmt *Body = ADC->getBody();
+        if (Body)
+          L = Body->getLocStart();
+        else
+          L = ADC->getDecl()->getLocEnd();
+        break;
+      }
+
+      L = UseEnd ? Parent->getLocEnd() : Parent->getLocStart();
+    } while (!L.isValid());
   }
 
   return L;

Added: cfe/trunk/test/Analysis/ctor-inlining.mm
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/ctor-inlining.mm?rev=160810&view=auto
==============================================================================
--- cfe/trunk/test/Analysis/ctor-inlining.mm (added)
+++ cfe/trunk/test/Analysis/ctor-inlining.mm Thu Jul 26 15:04:30 2012
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -analyze -analyzer-checker=core -fobjc-arc -cfg-add-initializers -cfg-add-implicit-dtors -Wno-null-dereference -verify %s
+
+struct Wrapper {
+  __strong id obj;
+};
+
+void test() {
+  Wrapper w;
+  // force a diagnostic
+  *(char *)0 = 1; // expected-warning{{Dereference of null pointer}}
+}

Modified: cfe/trunk/test/Analysis/dtor.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/dtor.cpp?rev=160810&r1=160809&r2=160810&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/dtor.cpp (original)
+++ cfe/trunk/test/Analysis/dtor.cpp Thu Jul 26 15:04:30 2012
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-store region -analyzer-ipa=inlining -cfg-add-implicit-dtors -cfg-add-initializers -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-store region -analyzer-ipa=inlining -cfg-add-implicit-dtors -cfg-add-initializers -Wno-null-dereference -verify %s
 
 void clang_analyzer_eval(bool);
 
@@ -154,3 +154,22 @@
   clang_analyzer_eval(i == 42); // expected-warning{{UNKNOWN}}
   clang_analyzer_eval(j == 42); // expected-warning{{UNKNOWN}}
 }
+
+
+
+// Don't crash on a default argument inside an initializer.
+struct DefaultArg {
+  DefaultArg(int x = 0) {}
+  ~DefaultArg();
+};
+
+struct InheritsDefaultArg : DefaultArg {
+  InheritsDefaultArg() {}
+  virtual ~InheritsDefaultArg();
+};
+
+void testDefaultArg() {
+  InheritsDefaultArg a;
+  // Force a bug to be emitted.
+  *(char *)0 = 1; // expected-warning{{Dereference of null pointer}}
+}





More information about the cfe-commits mailing list