diff options
author | Artem Dergachev <artem.dergachev@gmail.com> | 2018-03-12 23:36:12 +0000 |
---|---|---|
committer | Artem Dergachev <artem.dergachev@gmail.com> | 2018-03-12 23:36:12 +0000 |
commit | 09a7c0c77de0e48e819b8b07ee06095396e108f0 (patch) | |
tree | 5d2f66c569af4e8a109f95d9e012f2618a062ae6 /clang/lib | |
parent | 98a24bf76d08f2cd69c0205e0313cbcddcc658cb (diff) | |
download | bcm5719-llvm-09a7c0c77de0e48e819b8b07ee06095396e108f0.tar.gz bcm5719-llvm-09a7c0c77de0e48e819b8b07ee06095396e108f0.zip |
[analyzer] Support temporaries conjured by conservatively evaluated functions.
Properly perform destruction and lifetime extension of such temporaries.
C++ object-type return values of conservatively evaluated functions are now
represented as compound values of well-defined temporary object regions. The
function creates a region that represents the temporary object and will later
be used for destruction or materialization, invalidates it, and returns the
invalidated compound value of the object.
Differential Revision: https://reviews.llvm.org/D44131
llvm-svn: 327348
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp | 44 |
1 files changed, 30 insertions, 14 deletions
diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp index ede48161d93..5aace88cfa0 100644 --- a/clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp +++ b/clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp @@ -581,23 +581,39 @@ ProgramStateRef ExprEngine::bindReturnValue(const CallEvent &Call, return State->BindExpr(E, LCtx, ThisV); } - // Conjure a symbol if the return value is unknown. + SVal R; QualType ResultTy = Call.getResultType(); - SValBuilder &SVB = getSValBuilder(); unsigned Count = currBldrCtx->blockCount(); + if (auto RTC = getCurrentCFGElement().getAs<CFGCXXRecordTypedCall>()) { + // Conjure a temporary if the function returns an object by value. + MemRegionManager &MRMgr = svalBuilder.getRegionManager(); + const CXXTempObjectRegion *TR = MRMgr.getCXXTempObjectRegion(E, LCtx); + State = addAllNecessaryTemporaryInfo(State, RTC->getConstructionContext(), + LCtx, TR); + + // Invalidate the region so that it didn't look uninitialized. Don't notify + // the checkers. + State = State->invalidateRegions(TR, E, Count, LCtx, + /* CausedByPointerEscape=*/false, nullptr, + &Call, nullptr); + + R = State->getSVal(TR, E->getType()); + } else { + // Conjure a symbol if the return value is unknown. + + // See if we need to conjure a heap pointer instead of + // a regular unknown pointer. + bool IsHeapPointer = false; + if (const auto *CNE = dyn_cast<CXXNewExpr>(E)) + if (CNE->getOperatorNew()->isReplaceableGlobalAllocationFunction()) { + // FIXME: Delegate this to evalCall in MallocChecker? + IsHeapPointer = true; + } - // See if we need to conjure a heap pointer instead of - // a regular unknown pointer. - bool IsHeapPointer = false; - if (const auto *CNE = dyn_cast<CXXNewExpr>(E)) - if (CNE->getOperatorNew()->isReplaceableGlobalAllocationFunction()) { - // FIXME: Delegate this to evalCall in MallocChecker? - IsHeapPointer = true; - } - - SVal R = IsHeapPointer - ? SVB.getConjuredHeapSymbolVal(E, LCtx, Count) - : SVB.conjureSymbolVal(nullptr, E, LCtx, ResultTy, Count); + R = IsHeapPointer ? svalBuilder.getConjuredHeapSymbolVal(E, LCtx, Count) + : svalBuilder.conjureSymbolVal(nullptr, E, LCtx, ResultTy, + Count); + } return State->BindExpr(E, LCtx, R); } |