aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/Analysis/AnalysisContext.h5
-rw-r--r--include/clang/Analysis/CFG.h4
-rw-r--r--include/clang/Driver/CC1Options.td2
-rw-r--r--include/clang/StaticAnalyzer/Core/AnalyzerOptions.h11
-rw-r--r--lib/Analysis/AnalysisDeclContext.cpp6
-rw-r--r--lib/Analysis/CFG.cpp8
-rw-r--r--lib/Frontend/CompilerInvocation.cpp1
-rw-r--r--lib/StaticAnalyzer/Core/AnalysisManager.cpp5
-rw-r--r--lib/StaticAnalyzer/Core/AnalyzerOptions.cpp4
-rw-r--r--test/Analysis/auto-obj-dtors-cfg-output.cpp2
-rw-r--r--test/Analysis/dtor.cpp2
-rw-r--r--test/Analysis/dtors-in-dtor-cfg-output.cpp2
-rw-r--r--test/Analysis/malloc.cpp25
-rw-r--r--test/Analysis/temp-obj-dtors-cfg-output.cpp2
14 files changed, 60 insertions, 19 deletions
diff --git a/include/clang/Analysis/AnalysisContext.h b/include/clang/Analysis/AnalysisContext.h
index 46b4e93bb7..41b57b3104 100644
--- a/include/clang/Analysis/AnalysisContext.h
+++ b/include/clang/Analysis/AnalysisContext.h
@@ -382,8 +382,9 @@ class AnalysisDeclContextManager {
public:
AnalysisDeclContextManager(bool useUnoptimizedCFG = false,
- bool addImplicitDtors = false,
- bool addInitializers = false);
+ bool addImplicitDtors = false,
+ bool addInitializers = false,
+ bool addTemporaryDtors = false);
~AnalysisDeclContextManager();
diff --git a/include/clang/Analysis/CFG.h b/include/clang/Analysis/CFG.h
index 4d087e7498..30a1db2f62 100644
--- a/include/clang/Analysis/CFG.h
+++ b/include/clang/Analysis/CFG.h
@@ -568,6 +568,7 @@ public:
bool AddEHEdges;
bool AddInitializers;
bool AddImplicitDtors;
+ bool AddTemporaryDtors;
bool alwaysAdd(const Stmt *stmt) const {
return alwaysAddMask[stmt->getStmtClass()];
@@ -587,7 +588,8 @@ public:
: forcedBlkExprs(0), PruneTriviallyFalseEdges(true)
,AddEHEdges(false)
,AddInitializers(false)
- ,AddImplicitDtors(false) {}
+ ,AddImplicitDtors(false)
+ ,AddTemporaryDtors(false) {}
};
/// \brief Provides a custom implementation of the iterator class to have the
diff --git a/include/clang/Driver/CC1Options.td b/include/clang/Driver/CC1Options.td
index 8089a0a732..d65bf20991 100644
--- a/include/clang/Driver/CC1Options.td
+++ b/include/clang/Driver/CC1Options.td
@@ -37,8 +37,6 @@ def triple_EQ : Joined<"-triple=">, Alias<triple>;
def analysis_UnoptimizedCFG : Flag<"-unoptimized-cfg">,
HelpText<"Generate unoptimized CFGs for all analyses">;
-def analysis_CFGAddImplicitDtors : Flag<"-cfg-add-implicit-dtors">,
- HelpText<"Add C++ implicit destructors to CFGs for all analyses">;
def analyzer_store : Separate<"-analyzer-store">,
HelpText<"Source Code Analysis - Abstract Memory Store Models">;
diff --git a/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h b/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
index 1ed5658876..5dba158f12 100644
--- a/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
+++ b/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
@@ -147,7 +147,6 @@ public:
unsigned visualizeExplodedGraphWithGraphViz : 1;
unsigned visualizeExplodedGraphWithUbiGraph : 1;
unsigned UnoptimizedCFG : 1;
- unsigned CFGAddImplicitDtors : 1;
unsigned eagerlyTrimExplodedGraph : 1;
unsigned PrintStats : 1;
@@ -172,9 +171,18 @@ public:
/// Returns the option controlling which C++ member functions will be
/// considered for inlining.
///
+ /// This is controlled by the 'c++-inlining' config option.
+ ///
/// \sa CXXMemberInliningMode
bool mayInlineCXXMemberFunction(CXXInlineableMemberKind K) const;
+ /// Returns whether or not the destructors for C++ temporary objects should
+ /// be included in the CFG.
+ ///
+ /// This is controlled by the 'cfg-temporary-dtors' config option. Any
+ /// non-empty value is considered to be 'true'.
+ bool includeTemporaryDtorsInCFG() const;
+
public:
AnalyzerOptions() : CXXMemberInliningMode() {
AnalysisStoreOpt = RegionStoreModel;
@@ -191,7 +199,6 @@ public:
visualizeExplodedGraphWithGraphViz = 0;
visualizeExplodedGraphWithUbiGraph = 0;
UnoptimizedCFG = 0;
- CFGAddImplicitDtors = 0;
eagerlyTrimExplodedGraph = 0;
PrintStats = 0;
NoRetryExhausted = 0;
diff --git a/lib/Analysis/AnalysisDeclContext.cpp b/lib/Analysis/AnalysisDeclContext.cpp
index 7de7f395e8..f2ef0defd7 100644
--- a/lib/Analysis/AnalysisDeclContext.cpp
+++ b/lib/Analysis/AnalysisDeclContext.cpp
@@ -62,11 +62,13 @@ AnalysisDeclContext::AnalysisDeclContext(AnalysisDeclContextManager *Mgr,
}
AnalysisDeclContextManager::AnalysisDeclContextManager(bool useUnoptimizedCFG,
- bool addImplicitDtors,
- bool addInitializers) {
+ bool addImplicitDtors,
+ bool addInitializers,
+ bool addTemporaryDtors) {
cfgBuildOptions.PruneTriviallyFalseEdges = !useUnoptimizedCFG;
cfgBuildOptions.AddImplicitDtors = addImplicitDtors;
cfgBuildOptions.AddInitializers = addInitializers;
+ cfgBuildOptions.AddTemporaryDtors = addTemporaryDtors;
}
void AnalysisDeclContextManager::clear() {
diff --git a/lib/Analysis/CFG.cpp b/lib/Analysis/CFG.cpp
index f811fa3f0f..a179b6dffe 100644
--- a/lib/Analysis/CFG.cpp
+++ b/lib/Analysis/CFG.cpp
@@ -706,7 +706,7 @@ CFGBlock *CFGBuilder::addInitializer(CXXCtorInitializer *I) {
IsReference = FD->getType()->isReferenceType();
HasTemporaries = isa<ExprWithCleanups>(Init);
- if (BuildOpts.AddImplicitDtors && HasTemporaries) {
+ if (BuildOpts.AddTemporaryDtors && HasTemporaries) {
// Generate destructors for temporaries in initialization expression.
VisitForTemporaryDtors(cast<ExprWithCleanups>(Init)->getSubExpr(),
IsReference);
@@ -1617,7 +1617,7 @@ CFGBlock *CFGBuilder::VisitDeclSubExpr(DeclStmt *DS) {
IsReference = VD->getType()->isReferenceType();
HasTemporaries = isa<ExprWithCleanups>(Init);
- if (BuildOpts.AddImplicitDtors && HasTemporaries) {
+ if (BuildOpts.AddTemporaryDtors && HasTemporaries) {
// Generate destructors for temporaries in initialization expression.
VisitForTemporaryDtors(cast<ExprWithCleanups>(Init)->getSubExpr(),
IsReference);
@@ -2972,7 +2972,7 @@ CFGBlock *CFGBuilder::VisitCXXForRangeStmt(CXXForRangeStmt *S) {
CFGBlock *CFGBuilder::VisitExprWithCleanups(ExprWithCleanups *E,
AddStmtChoice asc) {
- if (BuildOpts.AddImplicitDtors) {
+ if (BuildOpts.AddTemporaryDtors) {
// If adding implicit destructors visit the full expression for adding
// destructors of temporaries.
VisitForTemporaryDtors(E->getSubExpr());
@@ -3052,6 +3052,8 @@ CFGBlock *CFGBuilder::VisitIndirectGotoStmt(IndirectGotoStmt *I) {
}
CFGBlock *CFGBuilder::VisitForTemporaryDtors(Stmt *E, bool BindToTemporary) {
+ assert(BuildOpts.AddImplicitDtors && BuildOpts.AddTemporaryDtors);
+
tryAgain:
if (!E) {
badCFG = true;
diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp
index bf1a80c94c..6d6dbfcc28 100644
--- a/lib/Frontend/CompilerInvocation.cpp
+++ b/lib/Frontend/CompilerInvocation.cpp
@@ -1130,7 +1130,6 @@ static bool ParseAnalyzerArgs(AnalyzerOptions &Opts, ArgList &Args,
Opts.eagerlyAssumeBinOpBifurcation = Args.hasArg(OPT_analyzer_eagerly_assume);
Opts.AnalyzeSpecificFunction = Args.getLastArgValue(OPT_analyze_function);
Opts.UnoptimizedCFG = Args.hasArg(OPT_analysis_UnoptimizedCFG);
- Opts.CFGAddImplicitDtors = Args.hasArg(OPT_analysis_CFGAddImplicitDtors);
Opts.TrimGraph = Args.hasArg(OPT_trim_egraph);
Opts.MaxNodes = Args.getLastArgIntValue(OPT_analyzer_max_nodes, 150000,Diags);
Opts.maxBlockVisitOnPath = Args.getLastArgIntValue(OPT_analyzer_max_loop, 4, Diags);
diff --git a/lib/StaticAnalyzer/Core/AnalysisManager.cpp b/lib/StaticAnalyzer/Core/AnalysisManager.cpp
index 6a01edf7ce..ebd2336080 100644
--- a/lib/StaticAnalyzer/Core/AnalysisManager.cpp
+++ b/lib/StaticAnalyzer/Core/AnalysisManager.cpp
@@ -22,8 +22,9 @@ AnalysisManager::AnalysisManager(ASTContext &ctx, DiagnosticsEngine &diags,
CheckerManager *checkerMgr,
const AnalyzerOptions &Options)
: AnaCtxMgr(Options.UnoptimizedCFG,
- Options.CFGAddImplicitDtors,
- /*addInitializers=*/true),
+ /*AddImplicitDtors=*/true,
+ /*AddInitializers=*/true,
+ Options.includeTemporaryDtorsInCFG()),
Ctx(ctx),
Diags(diags),
LangOpts(lang),
diff --git a/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp b/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp
index 5574a2f226..9e45a11528 100644
--- a/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp
+++ b/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp
@@ -46,3 +46,7 @@ AnalyzerOptions::mayInlineCXXMemberFunction(CXXInlineableMemberKind K) const {
return CXXMemberInliningMode >= K;
}
+
+bool AnalyzerOptions::includeTemporaryDtorsInCFG() const {
+ return !Config.lookup("cfg-temporary-dtors").empty();
+}
diff --git a/test/Analysis/auto-obj-dtors-cfg-output.cpp b/test/Analysis/auto-obj-dtors-cfg-output.cpp
index 566e6caed6..e4b49dc10f 100644
--- a/test/Analysis/auto-obj-dtors-cfg-output.cpp
+++ b/test/Analysis/auto-obj-dtors-cfg-output.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -analyze -analyzer-checker=debug.DumpCFG -cfg-add-implicit-dtors %s > %t 2>&1
+// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -analyze -analyzer-checker=debug.DumpCFG %s > %t 2>&1
// RUN: FileCheck --input-file=%t %s
// XPASS: *
diff --git a/test/Analysis/dtor.cpp b/test/Analysis/dtor.cpp
index a5d3d3f015..a762ebed12 100644
--- a/test/Analysis/dtor.cpp
+++ b/test/Analysis/dtor.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-ipa=inlining -analyzer-config c++-inlining=destructors -cfg-add-implicit-dtors -Wno-null-dereference -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-ipa=inlining -analyzer-config c++-inlining=destructors -Wno-null-dereference -verify %s
void clang_analyzer_eval(bool);
void clang_analyzer_checkInlined(bool);
diff --git a/test/Analysis/dtors-in-dtor-cfg-output.cpp b/test/Analysis/dtors-in-dtor-cfg-output.cpp
index 68ba37ebf3..f0546fc8bf 100644
--- a/test/Analysis/dtors-in-dtor-cfg-output.cpp
+++ b/test/Analysis/dtors-in-dtor-cfg-output.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=debug.DumpCFG -cfg-add-implicit-dtors %s 2>&1 | FileCheck %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=debug.DumpCFG %s 2>&1 | FileCheck %s
// XPASS: *
class A {
diff --git a/test/Analysis/malloc.cpp b/test/Analysis/malloc.cpp
index 864477b587..220d74625b 100644
--- a/test/Analysis/malloc.cpp
+++ b/test/Analysis/malloc.cpp
@@ -6,6 +6,11 @@ void free(void *);
void *realloc(void *ptr, size_t size);
void *calloc(size_t nmemb, size_t size);
+
+void checkThatMallocCheckerIsRunning() {
+ malloc(4); // expected-warning{{leak}}
+}
+
// Test for radar://11110132.
struct Foo {
mutable void* m_data;
@@ -35,3 +40,23 @@ void r11160612_3(CanFreeMemory* p) {
const_ptr_and_callback_def_param(0, x, 12, p->myFree);
}
+
+namespace PR13751 {
+ class OwningVector {
+ void **storage;
+ size_t length;
+ public:
+ OwningVector();
+ ~OwningVector();
+ void push_back(void *Item) {
+ storage[length++] = Item;
+ }
+ };
+
+ void testDestructors() {
+ OwningVector v;
+ v.push_back(malloc(4));
+ // no leak warning; freed in destructor
+ }
+}
+
diff --git a/test/Analysis/temp-obj-dtors-cfg-output.cpp b/test/Analysis/temp-obj-dtors-cfg-output.cpp
index 6dbbc821bb..d13083ddf0 100644
--- a/test/Analysis/temp-obj-dtors-cfg-output.cpp
+++ b/test/Analysis/temp-obj-dtors-cfg-output.cpp
@@ -1,5 +1,5 @@
// RUN: rm -f %t
-// RUN: %clang_cc1 -analyze -analyzer-checker=debug.DumpCFG -cfg-add-implicit-dtors %s > %t 2>&1
+// RUN: %clang_cc1 -analyze -analyzer-checker=debug.DumpCFG -analyzer-config cfg-temporary-dtors=1 %s > %t 2>&1
// RUN: FileCheck --input-file=%t %s
// XPASS: *