a.sidorin created this revision.
a.sidorin added reviewers: zaks.anna, dcoughlin, bshastry.
a.sidorin added a subscriber: cfe-commits.
This patch enables ScopeContext to track variable lifetime. It is RFC mostly
since the work on its dependencies is still not finished and it lacks some
tests.
Pre-discussion took place in cfe-dev:
* http://lists.llvm.org/pipermail/cfe-dev/2015-December/046653.html
*
http://clang-developers.42468.n3.nabble.com/Analyzer-ScopeContext-implementation-td4050861.html
StackLocalsSpaceRegion is still present to preserve current behaviour because
'cfg-scope-info' is false by default.
http://reviews.llvm.org/D19979
Files:
include/clang/Analysis/AnalysisContext.h
include/clang/Analysis/ProgramPoint.h
include/clang/StaticAnalyzer/Core/Checker.h
include/clang/StaticAnalyzer/Core/CheckerManager.h
include/clang/StaticAnalyzer/Core/PathSensitive/Environment.h
include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h
include/clang/StaticAnalyzer/Core/PathSensitive/Regions.def
include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h
lib/Analysis/AnalysisDeclContext.cpp
lib/StaticAnalyzer/Checkers/CheckerDocumentation.cpp
lib/StaticAnalyzer/Checkers/MacOSXAPIChecker.cpp
lib/StaticAnalyzer/Checkers/MallocChecker.cpp
lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp
lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
lib/StaticAnalyzer/Core/CheckerManager.cpp
lib/StaticAnalyzer/Core/CoreEngine.cpp
lib/StaticAnalyzer/Core/Environment.cpp
lib/StaticAnalyzer/Core/ExprEngine.cpp
lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
lib/StaticAnalyzer/Core/MemRegion.cpp
lib/StaticAnalyzer/Core/PathDiagnostic.cpp
lib/StaticAnalyzer/Core/Store.cpp
test/Analysis/scope-context.cpp
Index: test/Analysis/scope-context.cpp
===
--- /dev/null
+++ test/Analysis/scope-context.cpp
@@ -0,0 +1,24 @@
+// RUN: clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-store=region -verify -analyzer-config cfg-scope-info=true %s
+
+void clang_analyzer_eval(bool);
+
+void testEq() {
+ void *a[2];
+ for (int i = 0; i < 2; ++i) {
+int x[1];
+a[i] = [0];
+ }
+ clang_analyzer_eval(a[0] == a[1]); // expected-warning{{FALSE}}
+}
+
+void testBreak() {
+ for (int i = 0; i < 3; ++i) {
+{
+ int unused;
+ break;
+}
+ }
+ {
+int unused;
+ }
+}
Index: lib/StaticAnalyzer/Core/Store.cpp
===
--- lib/StaticAnalyzer/Core/Store.cpp
+++ lib/StaticAnalyzer/Core/Store.cpp
@@ -106,6 +106,7 @@
case MemRegion::HeapSpaceRegionKind:
case MemRegion::UnknownSpaceRegionKind:
case MemRegion::StaticGlobalSpaceRegionKind:
+case MemRegion::ScopeLocalSpaceRegionKind:
case MemRegion::GlobalInternalSpaceRegionKind:
case MemRegion::GlobalSystemSpaceRegionKind:
case MemRegion::GlobalImmutableSpaceRegionKind: {
Index: lib/StaticAnalyzer/Core/PathDiagnostic.cpp
===
--- lib/StaticAnalyzer/Core/PathDiagnostic.cpp
+++ lib/StaticAnalyzer/Core/PathDiagnostic.cpp
@@ -554,6 +554,14 @@
return PathDiagnosticLocation(Init.getInitializer()->getInit(),
SM, CallerCtx);
}
+ case CFGElement::ScopeBegin: {
+const Stmt *TriggerStmt = Source.castAs().getTriggerStmt();
+return PathDiagnosticLocation(TriggerStmt, SM, CallerCtx);
+ }
+ case CFGElement::ScopeEnd: {
+const Stmt *TriggerStmt = Source.castAs().getTriggerStmt();
+return PathDiagnosticLocation::createEnd(TriggerStmt, SM, CallerCtx);
+ }
case CFGElement::AutomaticObjectDtor: {
const CFGAutomaticObjDtor = Source.castAs();
return PathDiagnosticLocation::createEnd(Dtor.getTriggerStmt(),
@@ -694,6 +702,10 @@
return CEE->getCalleeContext()->getCallSite();
if (Optional PIPP = P.getAs())
return PIPP->getInitializer()->getInit();
+ if (Optional SE = P.getAs())
+return SE->getTriggerStmt();
+ if (Optional SEnt = P.getAs())
+return SEnt->getTriggerStmt();
return 0;
}
@@ -746,7 +758,7 @@
if (const BinaryOperator *B = dyn_cast(S))
return PathDiagnosticLocation::createOperatorLoc(B, SM);
-if (P.getAs())
+if (P.getAs() || P.getAs())
return PathDiagnosticLocation::createEnd(S, SM, LC);
if (S->getLocStart().isValid())
Index: lib/StaticAnalyzer/Core/MemRegion.cpp
===
--- lib/StaticAnalyzer/Core/MemRegion.cpp
+++ lib/StaticAnalyzer/Core/MemRegion.cpp
@@ -172,8 +172,15 @@
}
const StackFrameContext *VarRegion::getStackFrame() const {
- const StackSpaceRegion *SSR = dyn_cast(getMemorySpace());
- return SSR ? SSR->getStackFrame() : NULL;
+ const MemSpaceRegion *Space = getMemorySpace();
+ if (const StackSpaceRegion *StackSpace =