From 563ea2335d7d0df44bbfe8941f64523e8af1fc14 Mon Sep 17 00:00:00 2001 From: Jordan Rose Date: Fri, 3 Aug 2012 23:31:15 +0000 Subject: [PATCH] [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 --- lib/StaticAnalyzer/Core/ExprEngine.cpp | 9 +++++++-- lib/StaticAnalyzer/Core/ExprEngineCXX.cpp | 5 +++++ test/Analysis/initializer.cpp | 14 +++++++++++++- 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/lib/StaticAnalyzer/Core/ExprEngine.cpp b/lib/StaticAnalyzer/Core/ExprEngine.cpp index b46dc49a1b..b0435fb562 100644 --- a/lib/StaticAnalyzer/Core/ExprEngine.cpp +++ b/lib/StaticAnalyzer/Core/ExprEngine.cpp @@ -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(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. } diff --git a/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp b/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp index d0a0e32f74..44a860f689 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 @@ void ExprEngine::VisitCXXDestructor(QualType ObjectType, CallEventRef 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 f7a6fd7bea..d43c8cfd9a 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 @@ 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 // ------------------------------------ -- 2.40.0