[analyzer] Update initializer assertion for delegating constructors.

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
diff --git a/lib/StaticAnalyzer/Core/ExprEngine.cpp b/lib/StaticAnalyzer/Core/ExprEngine.cpp
index b46dc49..b0435fb 100644
--- a/lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ b/lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -360,8 +360,13 @@
 
   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 @@
       State = State->bindLoc(FieldLoc, InitVal);
     }
   } else {
-    assert(BMI->isBaseInitializer());
+    assert(BMI->isBaseInitializer() || BMI->isDelegatingInitializer());
     // We already did all the work when visiting the CXXConstructExpr.
   }
 
diff --git a/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp b/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
index d0a0e32..44a860f 100644
--- a/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
+++ b/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
@@ -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 @@
   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);
diff --git a/test/Analysis/initializer.cpp b/test/Analysis/initializer.cpp
index f7a6fd7..d43c8cf 100644
--- a/test/Analysis/initializer.cpp
+++ b/test/Analysis/initializer.cpp
@@ -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 @@
 }
 
 
+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
 // ------------------------------------