diff options
Diffstat (limited to 'clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp')
| -rw-r--r-- | clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp | 42 |
1 files changed, 11 insertions, 31 deletions
diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp index 5b1d8131583..fb906cb0951 100644 --- a/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp +++ b/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp @@ -84,16 +84,8 @@ void ExprEngine::performTrivialCopy(NodeBuilder &Bldr, ExplodedNode *Pred, } -/// Returns a region representing the first element of a (possibly -/// multi-dimensional) array, for the purposes of element construction or -/// destruction. -/// -/// On return, \p Ty will be set to the base type of the array. -/// -/// If the type is not an array type at all, the original value is returned. -/// Otherwise the "IsArray" flag is set. -static SVal makeZeroElementRegion(ProgramStateRef State, SVal LValue, - QualType &Ty, bool &IsArray) { +SVal ExprEngine::makeZeroElementRegion(ProgramStateRef State, SVal LValue, + QualType &Ty, bool &IsArray) { SValBuilder &SVB = State->getStateManager().getSValBuilder(); ASTContext &Ctx = SVB.getContext(); @@ -131,7 +123,7 @@ ExprEngine::getRegionForConstructedObject(const CXXConstructExpr *CE, if (CNE->isArray()) { // TODO: In fact, we need to call the constructor for every // allocated element, not just the first one! - CallOpts.IsArrayConstructorOrDestructor = true; + CallOpts.IsArrayCtorOrDtor = true; return getStoreManager().GetElementZeroRegion( MR, CNE->getType()->getPointeeType()); } @@ -143,7 +135,7 @@ ExprEngine::getRegionForConstructedObject(const CXXConstructExpr *CE, SVal LValue = State->getLValue(Var, LCtx); QualType Ty = Var->getType(); LValue = makeZeroElementRegion(State, LValue, Ty, - CallOpts.IsArrayConstructorOrDestructor); + CallOpts.IsArrayCtorOrDtor); return LValue.getAsRegion(); } else if (auto *RS = dyn_cast<ReturnStmt>(TriggerStmt)) { // TODO: We should construct into a CXXBindTemporaryExpr or a @@ -154,7 +146,7 @@ ExprEngine::getRegionForConstructedObject(const CXXConstructExpr *CE, // function, we should be able to take the call-site CFG element, // and it should contain (but right now it wouldn't) some sort of // construction context that'd give us the right temporary expression. - CallOpts.IsConstructorIntoTemporary = true; + CallOpts.IsTemporaryCtorOrDtor = true; return MRMgr.getCXXTempObjectRegion(CE, LCtx); } // TODO: Consider other directly initialized elements. @@ -177,7 +169,7 @@ ExprEngine::getRegionForConstructedObject(const CXXConstructExpr *CE, QualType Ty = Field->getType(); FieldVal = makeZeroElementRegion(State, FieldVal, Ty, - CallOpts.IsArrayConstructorOrDestructor); + CallOpts.IsArrayCtorOrDtor); return FieldVal.getAsRegion(); } @@ -187,7 +179,7 @@ ExprEngine::getRegionForConstructedObject(const CXXConstructExpr *CE, } // If we couldn't find an existing region to construct into, assume we're // constructing a temporary. Notify the caller of our failure. - CallOpts.IsConstructorWithImproperlyModeledTargetRegion = true; + CallOpts.IsCtorOrDtorWithImproperlyModeledTargetRegion = true; return MRMgr.getCXXTempObjectRegion(CE, LCtx); } @@ -273,7 +265,7 @@ void ExprEngine::VisitCXXConstructExpr(const CXXConstructExpr *CE, if (dyn_cast_or_null<InitListExpr>(LCtx->getParentMap().getParent(CE))) { MemRegionManager &MRMgr = getSValBuilder().getRegionManager(); Target = MRMgr.getCXXTempObjectRegion(CE, LCtx); - CallOpts.IsConstructorWithImproperlyModeledTargetRegion = true; + CallOpts.IsCtorOrDtorWithImproperlyModeledTargetRegion = true; break; } // FALLTHROUGH @@ -343,7 +335,7 @@ void ExprEngine::VisitCXXConstructExpr(const CXXConstructExpr *CE, if (CE->getConstructor()->isTrivial() && CE->getConstructor()->isCopyOrMoveConstructor() && - !CallOpts.IsArrayConstructorOrDestructor) { + !CallOpts.IsArrayCtorOrDtor) { // FIXME: Handle other kinds of trivial constructors as well. for (ExplodedNodeSet::iterator I = DstPreCall.begin(), E = DstPreCall.end(); I != E; ++I) @@ -400,23 +392,11 @@ void ExprEngine::VisitCXXDestructor(QualType ObjectType, const Stmt *S, bool IsBaseDtor, ExplodedNode *Pred, - ExplodedNodeSet &Dst) { + ExplodedNodeSet &Dst, + const EvalCallOptions &CallOpts) { const LocationContext *LCtx = Pred->getLocationContext(); ProgramStateRef State = Pred->getState(); - // FIXME: We need to run the same destructor on every element of the array. - // This workaround will just run the first destructor (which will still - // invalidate the entire array). - SVal DestVal = UnknownVal(); - if (Dest) - DestVal = loc::MemRegionVal(Dest); - - EvalCallOptions CallOpts; - DestVal = makeZeroElementRegion(State, DestVal, ObjectType, - CallOpts.IsArrayConstructorOrDestructor); - - Dest = DestVal.getAsRegion(); - const CXXRecordDecl *RecordDecl = ObjectType->getAsCXXRecordDecl(); assert(RecordDecl && "Only CXXRecordDecls should have destructors"); const CXXDestructorDecl *DtorDecl = RecordDecl->getDestructor(); |

