summaryrefslogtreecommitdiffstats
path: root/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
diff options
context:
space:
mode:
authorJordan Rose <jordan_rose@apple.com>2013-02-15 00:32:15 +0000
committerJordan Rose <jordan_rose@apple.com>2013-02-15 00:32:15 +0000
commit88bb563c4350ce67ebc435de046fa395e74c4670 (patch)
tree234adefe53031b8ee0b5fe8b6fbcbe414030f695 /clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
parent2516d7b0e87d1f74941c876e1d3bb3638ce8b204 (diff)
downloadbcm5719-llvm-88bb563c4350ce67ebc435de046fa395e74c4670.tar.gz
bcm5719-llvm-88bb563c4350ce67ebc435de046fa395e74c4670.zip
Re-apply "[analyzer] Model trivial copy/move ctors with an aggregate bind."
...after a host of optimizations related to the use of LazyCompoundVals (our implementation of aggregate binds). Originally applied in r173951. Reverted in r174069 because it was causing hangs. Re-applied in r174212. Reverted in r174265 because it was /still/ causing hangs. If this needs to be reverted again it will be punted to far in the future. llvm-svn: 175234
Diffstat (limited to 'clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp')
-rw-r--r--clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp54
1 files changed, 48 insertions, 6 deletions
diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
index 1f0c523ac66..fdd50a6b544 100644
--- a/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
@@ -49,6 +49,35 @@ void ExprEngine::CreateCXXTemporaryObject(const MaterializeTemporaryExpr *ME,
Bldr.generateNode(ME, Pred, state->BindExpr(ME, LCtx, V));
}
+void ExprEngine::performTrivialCopy(NodeBuilder &Bldr, ExplodedNode *Pred,
+ const CXXConstructorCall &Call) {
+ const CXXConstructExpr *CtorExpr = Call.getOriginExpr();
+ assert(CtorExpr->getConstructor()->isCopyOrMoveConstructor());
+ assert(CtorExpr->getConstructor()->isTrivial());
+
+ SVal ThisVal = Call.getCXXThisVal();
+ const LocationContext *LCtx = Pred->getLocationContext();
+
+ ExplodedNodeSet Dst;
+ Bldr.takeNodes(Pred);
+
+ SVal V = Call.getArgSVal(0);
+
+ // Make sure the value being copied is not unknown.
+ if (const Loc *L = dyn_cast<Loc>(&V))
+ V = Pred->getState()->getSVal(*L);
+
+ evalBind(Dst, CtorExpr, Pred, ThisVal, V, true);
+
+ PostStmt PS(CtorExpr, LCtx);
+ for (ExplodedNodeSet::iterator I = Dst.begin(), E = Dst.end();
+ I != E; ++I) {
+ ProgramStateRef State = (*I)->getState();
+ State = bindReturnValue(Call, LCtx, State);
+ Bldr.generateNode(PS, State, *I);
+ }
+}
+
void ExprEngine::VisitCXXConstructExpr(const CXXConstructExpr *CE,
ExplodedNode *Pred,
ExplodedNodeSet &destNodes) {
@@ -56,6 +85,7 @@ void ExprEngine::VisitCXXConstructExpr(const CXXConstructExpr *CE,
ProgramStateRef State = Pred->getState();
const MemRegion *Target = 0;
+ bool IsArray = false;
switch (CE->getConstructionKind()) {
case CXXConstructExpr::CK_Complete: {
@@ -79,6 +109,7 @@ void ExprEngine::VisitCXXConstructExpr(const CXXConstructExpr *CE,
Target = State->getLValue(AT->getElementType(),
getSValBuilder().makeZeroArrayIndex(),
Base).getAsRegion();
+ IsArray = true;
} else {
Target = State->getLValue(Var, LCtx).getAsRegion();
}
@@ -148,14 +179,25 @@ void ExprEngine::VisitCXXConstructExpr(const CXXConstructExpr *CE,
getCheckerManager().runCheckersForPreCall(DstPreCall, DstPreVisit,
*Call, *this);
- ExplodedNodeSet DstInvalidated;
- StmtNodeBuilder Bldr(DstPreCall, DstInvalidated, *currBldrCtx);
- for (ExplodedNodeSet::iterator I = DstPreCall.begin(), E = DstPreCall.end();
- I != E; ++I)
- defaultEvalCall(Bldr, *I, *Call);
+ ExplodedNodeSet DstEvaluated;
+ StmtNodeBuilder Bldr(DstPreCall, DstEvaluated, *currBldrCtx);
+
+ if (CE->getConstructor()->isTrivial() &&
+ CE->getConstructor()->isCopyOrMoveConstructor() &&
+ !IsArray) {
+ // FIXME: Handle other kinds of trivial constructors as well.
+ for (ExplodedNodeSet::iterator I = DstPreCall.begin(), E = DstPreCall.end();
+ I != E; ++I)
+ performTrivialCopy(Bldr, *I, *Call);
+
+ } else {
+ for (ExplodedNodeSet::iterator I = DstPreCall.begin(), E = DstPreCall.end();
+ I != E; ++I)
+ defaultEvalCall(Bldr, *I, *Call);
+ }
ExplodedNodeSet DstPostCall;
- getCheckerManager().runCheckersForPostCall(DstPostCall, DstInvalidated,
+ getCheckerManager().runCheckersForPostCall(DstPostCall, DstEvaluated,
*Call, *this);
getCheckerManager().runCheckersForPostStmt(destNodes, DstPostCall, CE, *this);
}
OpenPOWER on IntegriCloud