diff options
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); } |