]> granicus.if.org Git - clang/commitdiff
[analyzer] Update initializer assertion for delegating constructors.
authorJordan Rose <jordan_rose@apple.com>
Fri, 3 Aug 2012 23:31:15 +0000 (23:31 +0000)
committerJordan Rose <jordan_rose@apple.com>
Fri, 3 Aug 2012 23:31:15 +0000 (23:31 +0000)
Like base constructors, delegating constructors require no further
processing in the CFGInitializer node.

Also, add PrettyStackTraceLoc to the initializer and destructor logic
so we can get better stack traces in the future.

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

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

index b46dc49a1bfd8c352b97012a8bea387ec9a26781..b0435fb562e3b31a94ec955f539f8aa6f7215438 100644 (file)
@@ -360,8 +360,13 @@ void ExprEngine::ProcessInitializer(const CFGInitializer Init,
 
   ProgramStateRef State = Pred->getState();
 
-  // We don't set EntryNode and currentStmt. And we don't clean up state.
   const CXXCtorInitializer *BMI = Init.getInitializer();
+
+  PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(),
+                                BMI->getSourceLocation(),
+                                "Error evaluating initializer");
+
+  // We don't set EntryNode and currentStmt. And we don't clean up state.
   const StackFrameContext *stackFrame =
                            cast<StackFrameContext>(Pred->getLocationContext());
   const CXXConstructorDecl *decl =
@@ -383,7 +388,7 @@ void ExprEngine::ProcessInitializer(const CFGInitializer Init,
       State = State->bindLoc(FieldLoc, InitVal);
     }
   } else {
-    assert(BMI->isBaseInitializer());
+    assert(BMI->isBaseInitializer() || BMI->isDelegatingInitializer());
     // We already did all the work when visiting the CXXConstructExpr.
   }
 
index d0a0e32f74d120f0e18800c37cc54f36ab2e1213..44a860f689da155ae31aa4ac1f7a716220fcad7b 100644 (file)
@@ -17,6 +17,7 @@
 #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/StmtCXX.h"
+#include "clang/Basic/PrettyStackTrace.h"
 
 using namespace clang;
 using namespace ento;
@@ -172,6 +173,10 @@ void ExprEngine::VisitCXXDestructor(QualType ObjectType,
   CallEventRef<CXXDestructorCall> Call =
     CEMgr.getCXXDestructorCall(DtorDecl, S, Dest, State, LCtx);
 
+  PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(),
+                                Call->getSourceRange().getBegin(),
+                                "Error evaluating destructor");
+
   ExplodedNodeSet DstPreCall;
   getCheckerManager().runCheckersForPreCall(DstPreCall, Pred,
                                             *Call, *this);
index f7a6fd7bea97d0995db5b49d5834df847033cabc..d43c8cfd9a0a98611b97fd9606c3018c0b811703 100644 (file)
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-store region -cfg-add-implicit-dtors -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-store region -cfg-add-implicit-dtors -std=c++11 -verify %s
 
 // We don't inline constructors unless we have destructors turned on.
 
@@ -45,6 +45,18 @@ void testIndirectMember() {
 }
 
 
+struct DelegatingConstructor {
+  int x;
+  DelegatingConstructor(int y) { x = y; }
+  DelegatingConstructor() : DelegatingConstructor(42) {}
+};
+
+void testDelegatingConstructor() {
+  DelegatingConstructor obj;
+  clang_analyzer_eval(obj.x == 42); // expected-warning{{TRUE}}
+}
+
+
 // ------------------------------------
 // False negatives
 // ------------------------------------