diff options
Diffstat (limited to 'clang/lib/StaticAnalyzer/Core')
-rw-r--r-- | clang/lib/StaticAnalyzer/Core/ExprEngine.cpp | 4 | ||||
-rw-r--r-- | clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp | 5 | ||||
-rw-r--r-- | clang/lib/StaticAnalyzer/Core/ProgramState.cpp | 25 | ||||
-rw-r--r-- | clang/lib/StaticAnalyzer/Core/RegionStore.cpp | 40 | ||||
-rw-r--r-- | clang/lib/StaticAnalyzer/Core/Store.cpp | 4 |
5 files changed, 44 insertions, 34 deletions
diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp index d0ebb223e94..6956c6dbe83 100644 --- a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp +++ b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp @@ -348,7 +348,9 @@ ExprEngine::createTemporaryRegionIfNeeded(ProgramStateRef State, break; case SubobjectAdjustment::MemberPointerAdjustment: // FIXME: Unimplemented. - State = State->bindDefault(Reg, UnknownVal(), LC); + State = State->invalidateRegions(Reg, InitWithAdjustments, + currBldrCtx->blockCount(), LC, true, + nullptr, nullptr, nullptr); return State; } } diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp index 9152b41e1e1..90a35f39324 100644 --- a/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp +++ b/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp @@ -375,9 +375,6 @@ void ExprEngine::VisitCXXConstructExpr(const CXXConstructExpr *CE, I != E; ++I) { ProgramStateRef State = (*I)->getState(); if (CE->requiresZeroInitialization()) { - // Type of the zero doesn't matter. - SVal ZeroVal = svalBuilder.makeZeroVal(getContext().CharTy); - // FIXME: Once we properly handle constructors in new-expressions, we'll // need to invalidate the region before setting a default value, to make // sure there aren't any lingering bindings around. This probably needs @@ -390,7 +387,7 @@ void ExprEngine::VisitCXXConstructExpr(const CXXConstructExpr *CE, // actually make things worse. Placement new makes this tricky as well, // since it's then possible to be initializing one part of a multi- // dimensional array. - State = State->bindDefault(loc::MemRegionVal(Target), ZeroVal, LCtx); + State = State->bindDefaultZero(loc::MemRegionVal(Target), LCtx); } State = addAllNecessaryTemporaryInfo(State, CC, LCtx, Target); diff --git a/clang/lib/StaticAnalyzer/Core/ProgramState.cpp b/clang/lib/StaticAnalyzer/Core/ProgramState.cpp index deb2e4a5074..141863d2ac8 100644 --- a/clang/lib/StaticAnalyzer/Core/ProgramState.cpp +++ b/clang/lib/StaticAnalyzer/Core/ProgramState.cpp @@ -126,16 +126,27 @@ ProgramStateRef ProgramState::bindLoc(Loc LV, return newState; } -ProgramStateRef ProgramState::bindDefault(SVal loc, - SVal V, - const LocationContext *LCtx) const { +ProgramStateRef +ProgramState::bindDefaultInitial(SVal loc, SVal V, + const LocationContext *LCtx) const { + ProgramStateManager &Mgr = getStateManager(); + const MemRegion *R = loc.castAs<loc::MemRegionVal>().getRegion(); + const StoreRef &newStore = Mgr.StoreMgr->BindDefaultInitial(getStore(), R, V); + ProgramStateRef new_state = makeWithStore(newStore); + return Mgr.getOwningEngine() + ? Mgr.getOwningEngine()->processRegionChange(new_state, R, LCtx) + : new_state; +} + +ProgramStateRef +ProgramState::bindDefaultZero(SVal loc, const LocationContext *LCtx) const { ProgramStateManager &Mgr = getStateManager(); const MemRegion *R = loc.castAs<loc::MemRegionVal>().getRegion(); - const StoreRef &newStore = Mgr.StoreMgr->BindDefault(getStore(), R, V); + const StoreRef &newStore = Mgr.StoreMgr->BindDefaultZero(getStore(), R); ProgramStateRef new_state = makeWithStore(newStore); - return Mgr.getOwningEngine() ? - Mgr.getOwningEngine()->processRegionChange(new_state, R, LCtx) : - new_state; + return Mgr.getOwningEngine() + ? Mgr.getOwningEngine()->processRegionChange(new_state, R, LCtx) + : new_state; } typedef ArrayRef<const MemRegion *> RegionList; diff --git a/clang/lib/StaticAnalyzer/Core/RegionStore.cpp b/clang/lib/StaticAnalyzer/Core/RegionStore.cpp index 7f2c1d58262..d4624c089da 100644 --- a/clang/lib/StaticAnalyzer/Core/RegionStore.cpp +++ b/clang/lib/StaticAnalyzer/Core/RegionStore.cpp @@ -409,8 +409,22 @@ public: // Part of public interface to class. RegionBindingsRef bind(RegionBindingsConstRef B, Loc LV, SVal V); - // BindDefault is only used to initialize a region with a default value. - StoreRef BindDefault(Store store, const MemRegion *R, SVal V) override { + // BindDefaultInitial is only used to initialize a region with + // a default value. + StoreRef BindDefaultInitial(Store store, const MemRegion *R, + SVal V) override { + RegionBindingsRef B = getRegionBindings(store); + // Use other APIs when you have to wipe the region that was initialized + // earlier. + assert(!(B.getDefaultBinding(R) || B.getDirectBinding(R)) && + "Double initialization!"); + B = B.addBinding(BindingKey::Make(R, BindingKey::Default), V); + return StoreRef(B.asImmutableMap().getRootWithoutRetain(), *this); + } + + // BindDefaultZero is used for zeroing constructors that may accidentally + // overwrite existing bindings. + StoreRef BindDefaultZero(Store store, const MemRegion *R) override { // FIXME: The offsets of empty bases can be tricky because of // of the so called "empty base class optimization". // If a base class has been optimized out @@ -420,24 +434,14 @@ public: // Part of public interface to class. // and trying to infer them from offsets/alignments // seems to be error-prone and non-trivial because of the trailing padding. // As a temporary mitigation we don't create bindings for empty bases. - if (R->getKind() == MemRegion::CXXBaseObjectRegionKind && - cast<CXXBaseObjectRegion>(R)->getDecl()->isEmpty()) - return StoreRef(store, *this); + if (const auto *BR = dyn_cast<CXXBaseObjectRegion>(R)) + if (BR->getDecl()->isEmpty()) + return StoreRef(store, *this); RegionBindingsRef B = getRegionBindings(store); - assert(!B.lookup(R, BindingKey::Direct)); - - BindingKey Key = BindingKey::Make(R, BindingKey::Default); - if (B.lookup(Key)) { - const SubRegion *SR = cast<SubRegion>(R); - assert(SR->getAsOffset().getOffset() == - SR->getSuperRegion()->getAsOffset().getOffset() && - "A default value must come from a super-region"); - B = removeSubRegionBindings(B, SR); - } else { - B = B.addBinding(Key, V); - } - + SVal V = svalBuilder.makeZeroVal(Ctx.CharTy); + B = removeSubRegionBindings(B, cast<SubRegion>(R)); + B = B.addBinding(BindingKey::Make(R, BindingKey::Default), V); return StoreRef(B.asImmutableMap().getRootWithoutRetain(), *this); } diff --git a/clang/lib/StaticAnalyzer/Core/Store.cpp b/clang/lib/StaticAnalyzer/Core/Store.cpp index e78ac0fe007..eeafaf61084 100644 --- a/clang/lib/StaticAnalyzer/Core/Store.cpp +++ b/clang/lib/StaticAnalyzer/Core/Store.cpp @@ -65,10 +65,6 @@ const ElementRegion *StoreManager::MakeElementRegion(const SubRegion *Base, return MRMgr.getElementRegion(EleTy, idx, Base, svalBuilder.getContext()); } -StoreRef StoreManager::BindDefault(Store store, const MemRegion *R, SVal V) { - return StoreRef(store, *this); -} - const ElementRegion *StoreManager::GetElementZeroRegion(const SubRegion *R, QualType T) { NonLoc idx = svalBuilder.makeZeroArrayIndex(); |