summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorArtem Dergachev <artem.dergachev@gmail.com>2018-03-12 23:36:12 +0000
committerArtem Dergachev <artem.dergachev@gmail.com>2018-03-12 23:36:12 +0000
commit09a7c0c77de0e48e819b8b07ee06095396e108f0 (patch)
tree5d2f66c569af4e8a109f95d9e012f2618a062ae6 /clang/lib
parent98a24bf76d08f2cd69c0205e0313cbcddcc658cb (diff)
downloadbcm5719-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.cpp44
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);
}
OpenPOWER on IntegriCloud