diff options
author | Gabor Horvath <xazax.hun@gmail.com> | 2015-09-11 16:55:01 +0000 |
---|---|---|
committer | Gabor Horvath <xazax.hun@gmail.com> | 2015-09-11 16:55:01 +0000 |
commit | 15843343b67a37c8859bd7f84d2f34b0f7eead85 (patch) | |
tree | d78eac474e240b69e50692102685ac4a4dd54113 /clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp | |
parent | 62921286982916bf03158f31fb053882faee7bf1 (diff) | |
download | bcm5719-llvm-15843343b67a37c8859bd7f84d2f34b0f7eead85.tar.gz bcm5719-llvm-15843343b67a37c8859bd7f84d2f34b0f7eead85.zip |
[Static Analyzer] Lambda support.
Differential Revision: http://reviews.llvm.org/D12652
llvm-svn: 247426
Diffstat (limited to 'clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp')
-rw-r--r-- | clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp index 849ca960ade..1958d7bc4b1 100644 --- a/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp +++ b/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp @@ -513,3 +513,41 @@ void ExprEngine::VisitCXXThisExpr(const CXXThisExpr *TE, ExplodedNode *Pred, SVal V = state->getSVal(loc::MemRegionVal(R)); Bldr.generateNode(TE, Pred, state->BindExpr(TE, LCtx, V)); } + +void ExprEngine::VisitLambdaExpr(const LambdaExpr *LE, ExplodedNode *Pred, + ExplodedNodeSet &Dst) { + const LocationContext *LocCtxt = Pred->getLocationContext(); + + // Get the region of the lambda itself. + const MemRegion *R = svalBuilder.getRegionManager().getCXXTempObjectRegion( + LE, LocCtxt); + SVal V = loc::MemRegionVal(R); + + ProgramStateRef State = Pred->getState(); + + // If we created a new MemRegion for the lambda, we should explicitly bind + // the captures. + CXXRecordDecl::field_iterator CurField = LE->getLambdaClass()->field_begin(); + for (LambdaExpr::const_capture_init_iterator i = LE->capture_init_begin(), + e = LE->capture_init_end(); + i != e; ++i, ++CurField) { + SVal Field = State->getLValue(*CurField, V); + SVal InitExpr = State->getSVal(*i, LocCtxt); + State = State->bindLoc(Field, InitExpr); + } + + // Decay the Loc into an RValue, because there might be a + // MaterializeTemporaryExpr node above this one which expects the bound value + // to be an RValue. + SVal LambdaRVal = State->getSVal(R); + + ExplodedNodeSet Tmp; + StmtNodeBuilder Bldr(Pred, Tmp, *currBldrCtx); + // FIXME: is this the right program point kind? + Bldr.generateNode(LE, Pred, + State->BindExpr(LE, LocCtxt, LambdaRVal), + nullptr, ProgramPoint::PostLValueKind); + + // FIXME: Move all post/pre visits to ::Visit(). + getCheckerManager().runCheckersForPostStmt(Dst, Tmp, LE, *this); +} |