r186521 - [analyzer] Handle C++11 member initializer expressions.
Jordan Rose
jordan_rose at apple.com
Wed Jul 17 10:16:43 PDT 2013
Author: jrose
Date: Wed Jul 17 12:16:42 2013
New Revision: 186521
URL: http://llvm.org/viewvc/llvm-project?rev=186521&view=rev
Log:
[analyzer] Handle C++11 member initializer expressions.
Previously, we would simply abort the path when we saw a default member
initialization; now, we actually attempt to evaluate it. Like default
arguments, the contents of these expressions are not actually part of the
current function, so we fall back to constant evaluation.
Modified:
cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
cfe/trunk/test/Analysis/initializer.cpp
Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp?rev=186521&r1=186520&r2=186521&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp Wed Jul 17 12:16:42 2013
@@ -612,7 +612,6 @@ void ExprEngine::Visit(const Stmt *S, Ex
switch (S->getStmtClass()) {
// C++ and ARC stuff we don't support yet.
case Expr::ObjCIndirectCopyRestoreExprClass:
- case Stmt::CXXDefaultInitExprClass:
case Stmt::CXXDependentScopeMemberExprClass:
case Stmt::CXXPseudoDestructorExprClass:
case Stmt::CXXTryStmtClass:
@@ -737,7 +736,8 @@ void ExprEngine::Visit(const Stmt *S, Ex
break;
}
- case Stmt::CXXDefaultArgExprClass: {
+ case Stmt::CXXDefaultArgExprClass:
+ case Stmt::CXXDefaultInitExprClass: {
Bldr.takeNodes(Pred);
ExplodedNodeSet PreVisit;
getCheckerManager().runCheckersForPreStmt(PreVisit, Pred, S, *this);
@@ -745,9 +745,13 @@ void ExprEngine::Visit(const Stmt *S, Ex
ExplodedNodeSet Tmp;
StmtNodeBuilder Bldr2(PreVisit, Tmp, *currBldrCtx);
- const LocationContext *LCtx = Pred->getLocationContext();
- const CXXDefaultArgExpr *DefaultE = cast<CXXDefaultArgExpr>(S);
- const Expr *ArgE = DefaultE->getExpr();
+ const Expr *ArgE;
+ if (const CXXDefaultArgExpr *DefE = dyn_cast<CXXDefaultArgExpr>(S))
+ ArgE = DefE->getExpr();
+ else if (const CXXDefaultInitExpr *DefE = dyn_cast<CXXDefaultInitExpr>(S))
+ ArgE = DefE->getExpr();
+ else
+ llvm_unreachable("unknown constant wrapper kind");
bool IsTemporary = false;
if (const MaterializeTemporaryExpr *MTE =
@@ -760,13 +764,15 @@ void ExprEngine::Visit(const Stmt *S, Ex
if (!ConstantVal)
ConstantVal = UnknownVal();
+ const LocationContext *LCtx = Pred->getLocationContext();
for (ExplodedNodeSet::iterator I = PreVisit.begin(), E = PreVisit.end();
I != E; ++I) {
ProgramStateRef State = (*I)->getState();
- State = State->BindExpr(DefaultE, LCtx, *ConstantVal);
+ State = State->BindExpr(S, LCtx, *ConstantVal);
if (IsTemporary)
- State = createTemporaryRegionIfNeeded(State, LCtx, DefaultE,
- DefaultE);
+ State = createTemporaryRegionIfNeeded(State, LCtx,
+ cast<Expr>(S),
+ cast<Expr>(S));
Bldr2.generateNode(S, *I, State);
}
Modified: cfe/trunk/test/Analysis/initializer.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/initializer.cpp?rev=186521&r1=186520&r2=186521&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/initializer.cpp (original)
+++ cfe/trunk/test/Analysis/initializer.cpp Wed Jul 17 12:16:42 2013
@@ -109,3 +109,37 @@ namespace DefaultConstructorWithCleanups
return w.arr[0].value; // no-warning
}
}
+
+namespace DefaultMemberInitializers {
+ struct Wrapper {
+ int value = 42;
+
+ Wrapper() {}
+ Wrapper(int x) : value(x) {}
+ Wrapper(bool) {}
+ };
+
+ void test() {
+ Wrapper w1;
+ clang_analyzer_eval(w1.value == 42); // expected-warning{{TRUE}}
+
+ Wrapper w2(50);
+ clang_analyzer_eval(w2.value == 50); // expected-warning{{TRUE}}
+
+ Wrapper w3(false);
+ clang_analyzer_eval(w3.value == 42); // expected-warning{{TRUE}}
+ }
+
+ struct StringWrapper {
+ const char s[4] = "abc";
+ const char *p = "xyz";
+
+ StringWrapper(bool) {}
+ };
+
+ void testString() {
+ StringWrapper w(true);
+ clang_analyzer_eval(w.s[1] == 'b'); // expected-warning{{TRUE}}
+ clang_analyzer_eval(w.p[1] == 'y'); // expected-warning{{TRUE}}
+ }
+}
More information about the cfe-commits
mailing list