[cfe-commits] r78268 - in /cfe/trunk: include/clang/Analysis/PathSensitive/BasicValueFactory.h include/clang/Analysis/PathSensitive/MemRegion.h include/clang/Analysis/PathSensitive/SVals.h include/clang/Analysis/PathSensitive/ValueManager.h lib/Analysis/BasicValueFactory.cpp lib/Analysis/RegionStore.cpp lib/Analysis/SVals.cpp
Ted Kremenek
kremenek at apple.com
Wed Aug 5 18:21:10 PDT 2009
Author: kremenek
Date: Wed Aug 5 20:20:57 2009
New Revision: 78268
URL: http://llvm.org/viewvc/llvm-project?rev=78268&view=rev
Log:
Implement lazy "copying" of structures and arrays in RegionStore. While
RegionStore already lazily abstracted the contents of arrays and structs, when
doing an assignment from one array/struct to another we did an explicit
element-wise copy, which resulted in a loss of laziness and huge performance
problem when analyzing many code bases.
Now RegionStoreManager handles such assignments using a new SVal could
'LazyCompoundSVal', which basically means the value of a given struct or array
(a MemRegion*) in a specific state (GRState). When we do a load from a field
whose encompassing struct binds to a LazyCompoundSVal, we essentially do a field
lookup in the original structure. This means we have essentially zero copying of
data for structs/arrays and everything stays lazy.
Modified:
cfe/trunk/include/clang/Analysis/PathSensitive/BasicValueFactory.h
cfe/trunk/include/clang/Analysis/PathSensitive/MemRegion.h
cfe/trunk/include/clang/Analysis/PathSensitive/SVals.h
cfe/trunk/include/clang/Analysis/PathSensitive/ValueManager.h
cfe/trunk/lib/Analysis/BasicValueFactory.cpp
cfe/trunk/lib/Analysis/RegionStore.cpp
cfe/trunk/lib/Analysis/SVals.cpp
Modified: cfe/trunk/include/clang/Analysis/PathSensitive/BasicValueFactory.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathSensitive/BasicValueFactory.h?rev=78268&r1=78267&r2=78268&view=diff
==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/BasicValueFactory.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/BasicValueFactory.h Wed Aug 5 20:20:57 2009
@@ -25,6 +25,8 @@
namespace clang {
+ class GRState;
+
class CompoundValData : public llvm::FoldingSetNode {
QualType T;
llvm::ImmutableList<SVal> L;
@@ -43,6 +45,22 @@
void Profile(llvm::FoldingSetNodeID& ID) { Profile(ID, T, L); }
};
+class LazyCompoundValData : public llvm::FoldingSetNode {
+ const GRState *state;
+ const TypedRegion *region;
+public:
+ LazyCompoundValData(const GRState *st, const TypedRegion *r)
+ : state(st), region(r) {}
+
+ const GRState *getState() const { return state; }
+ const TypedRegion *getRegion() const { return region; }
+
+ static void Profile(llvm::FoldingSetNodeID& ID, const GRState *state,
+ const TypedRegion *region);
+
+ void Profile(llvm::FoldingSetNodeID& ID) { Profile(ID, state, region); }
+};
+
class BasicValueFactory {
typedef llvm::FoldingSet<llvm::FoldingSetNodeWrapper<llvm::APSInt> >
APSIntSetTy;
@@ -56,6 +74,7 @@
llvm::ImmutableList<SVal>::Factory SValListFactory;
llvm::FoldingSet<CompoundValData> CompoundValDataSet;
+ llvm::FoldingSet<LazyCompoundValData> LazyCompoundValDataSet;
public:
BasicValueFactory(ASTContext& ctx, llvm::BumpPtrAllocator& Alloc)
@@ -138,9 +157,12 @@
return getTruthValue(b, Ctx.IntTy);
}
- const CompoundValData* getCompoundValData(QualType T,
+ const CompoundValData *getCompoundValData(QualType T,
llvm::ImmutableList<SVal> Vals);
+ const LazyCompoundValData *getLazyCompoundValData(const GRState *state,
+ const TypedRegion *region);
+
llvm::ImmutableList<SVal> getEmptySValList() {
return SValListFactory.GetEmptyList();
}
Modified: cfe/trunk/include/clang/Analysis/PathSensitive/MemRegion.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathSensitive/MemRegion.h?rev=78268&r1=78267&r2=78268&view=diff
==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/MemRegion.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/MemRegion.h Wed Aug 5 20:20:57 2009
@@ -638,16 +638,27 @@
/// getElementRegion - Retrieve the memory region associated with the
/// associated element type, index, and super region.
- ElementRegion* getElementRegion(QualType elementType, SVal Idx,
+ ElementRegion *getElementRegion(QualType elementType, SVal Idx,
const MemRegion* superRegion,ASTContext &Ctx);
+
+ ElementRegion *getElementRegionWithSuper(const ElementRegion *ER,
+ const MemRegion *superRegion) {
+ return getElementRegion(ER->getElementType(), ER->getIndex(),
+ superRegion, ER->getContext());
+ }
/// getFieldRegion - Retrieve or create the memory region associated with
/// a specified FieldDecl. 'superRegion' corresponds to the containing
/// memory region (which typically represents the memory representing
/// a structure or class).
- FieldRegion* getFieldRegion(const FieldDecl* fd,
+ FieldRegion *getFieldRegion(const FieldDecl* fd,
const MemRegion* superRegion);
+ FieldRegion *getFieldRegionWithSuper(const FieldRegion *FR,
+ const MemRegion *superRegion) {
+ return getFieldRegion(FR->getDecl(), superRegion);
+ }
+
/// getObjCObjectRegion - Retrieve or create the memory region associated with
/// the instance of a specified Objective-C class.
ObjCObjectRegion* getObjCObjectRegion(const ObjCInterfaceDecl* ID,
Modified: cfe/trunk/include/clang/Analysis/PathSensitive/SVals.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathSensitive/SVals.h?rev=78268&r1=78267&r2=78268&view=diff
==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/SVals.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/SVals.h Wed Aug 5 20:20:57 2009
@@ -30,8 +30,11 @@
namespace clang {
class CompoundValData;
+class LazyCompoundValData;
+class GRState;
class BasicValueFactory;
class MemRegion;
+class TypedRegion;
class MemRegionManager;
class GRStateManager;
class ValueManager;
@@ -211,7 +214,7 @@
namespace nonloc {
enum Kind { ConcreteIntKind, SymbolValKind, SymExprValKind,
- LocAsIntegerKind, CompoundValKind };
+ LocAsIntegerKind, CompoundValKind, LazyCompoundValKind };
class SymbolVal : public NonLoc {
public:
@@ -334,6 +337,24 @@
}
};
+class LazyCompoundVal : public NonLoc {
+ friend class clang::ValueManager;
+
+ LazyCompoundVal(const LazyCompoundValData *D)
+ : NonLoc(LazyCompoundValKind, D) {}
+public:
+ const GRState *getState() const;
+ const TypedRegion *getRegion() const;
+
+ static bool classof(const SVal *V) {
+ return V->getBaseKind() == NonLocKind &&
+ V->getSubKind() == LazyCompoundValKind;
+ }
+ static bool classof(const NonLoc *V) {
+ return V->getSubKind() == LazyCompoundValKind;
+ }
+};
+
} // end namespace clang::nonloc
//==------------------------------------------------------------------------==//
Modified: cfe/trunk/include/clang/Analysis/PathSensitive/ValueManager.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathSensitive/ValueManager.h?rev=78268&r1=78267&r2=78268&view=diff
==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/ValueManager.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/ValueManager.h Wed Aug 5 20:20:57 2009
@@ -113,6 +113,10 @@
NonLoc makeCompoundVal(QualType T, llvm::ImmutableList<SVal> Vals) {
return nonloc::CompoundVal(BasicVals.getCompoundValData(T, Vals));
}
+
+ NonLoc makeLazyCompoundVal(const GRState *state, const TypedRegion *R) {
+ return nonloc::LazyCompoundVal(BasicVals.getLazyCompoundValData(state, R));
+ }
NonLoc makeZeroArrayIndex() {
return nonloc::ConcreteInt(BasicVals.getValue(0, ArrayIndexTy));
Modified: cfe/trunk/lib/Analysis/BasicValueFactory.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/BasicValueFactory.cpp?rev=78268&r1=78267&r2=78268&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/BasicValueFactory.cpp (original)
+++ cfe/trunk/lib/Analysis/BasicValueFactory.cpp Wed Aug 5 20:20:57 2009
@@ -23,6 +23,13 @@
ID.AddPointer(L.getInternalPointer());
}
+void LazyCompoundValData::Profile(llvm::FoldingSetNodeID& ID,
+ const GRState *state,
+ const TypedRegion *region) {
+ ID.AddPointer(state);
+ ID.AddPointer(region);
+}
+
typedef std::pair<SVal, uintptr_t> SValData;
typedef std::pair<SVal, SVal> SValPair;
@@ -116,6 +123,25 @@
return D;
}
+const LazyCompoundValData*
+BasicValueFactory::getLazyCompoundValData(const GRState *state,
+ const TypedRegion *region) {
+ llvm::FoldingSetNodeID ID;
+ LazyCompoundValData::Profile(ID, state, region);
+ void* InsertPos;
+
+ LazyCompoundValData *D =
+ LazyCompoundValDataSet.FindNodeOrInsertPos(ID, InsertPos);
+
+ if (!D) {
+ D = (LazyCompoundValData*) BPAlloc.Allocate<LazyCompoundValData>();
+ new (D) LazyCompoundValData(state, region);
+ LazyCompoundValDataSet.InsertNode(D, InsertPos);
+ }
+
+ return D;
+}
+
const llvm::APSInt*
BasicValueFactory::EvaluateAPSInt(BinaryOperator::Opcode Op,
const llvm::APSInt& V1, const llvm::APSInt& V2) {
Modified: cfe/trunk/lib/Analysis/RegionStore.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/RegionStore.cpp?rev=78268&r1=78267&r2=78268&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/RegionStore.cpp (original)
+++ cfe/trunk/lib/Analysis/RegionStore.cpp Wed Aug 5 20:20:57 2009
@@ -28,6 +28,7 @@
using namespace clang;
#define HEAP_UNDEFINED 0
+#define USE_EXPLICIT_COMPOUND 0
// Actual Store type.
typedef llvm::ImmutableMap<const MemRegion*, SVal> RegionBindingsTy;
@@ -130,6 +131,8 @@
I->second = F.Add(I->second, SubRegion);
return false;
}
+
+ void process(llvm::SmallVectorImpl<const SubRegion*> &WL, const SubRegion *R);
~RegionStoreSubRegionMap() {}
@@ -246,9 +249,11 @@
const Expr *E, unsigned Count);
private:
- RegionBindingsTy RemoveSubRegionBindings(RegionBindingsTy B,
- const MemRegion *R,
- RegionStoreSubRegionMap &M);
+ void RemoveSubRegionBindings(RegionBindingsTy &B,
+ RegionDefaultValue::MapTy &DVM,
+ RegionDefaultValue::MapTy::Factory &DVMFactory,
+ const MemRegion *R,
+ RegionStoreSubRegionMap &M);
public:
const GRState *Bind(const GRState *state, Loc LV, SVal V);
@@ -313,6 +318,13 @@
SVal RetrieveStruct(const GRState *St, const TypedRegion* R);
SVal RetrieveArray(const GRState *St, const TypedRegion* R);
+
+ std::pair<const GRState*, const MemRegion*>
+ GetLazyBinding(RegionBindingsTy B, const MemRegion *R);
+
+ const GRState* CopyLazyBindings(nonloc::LazyCompoundVal V,
+ const GRState *state,
+ const TypedRegion *R);
//===------------------------------------------------------------------===//
// State pruning.
@@ -381,37 +393,38 @@
return new RegionStoreManager(StMgr, F);
}
+void
+RegionStoreSubRegionMap::process(llvm::SmallVectorImpl<const SubRegion*> &WL,
+ const SubRegion *R) {
+ const MemRegion *superR = R->getSuperRegion();
+ if (add(superR, R))
+ if (const SubRegion *sr = dyn_cast<SubRegion>(superR))
+ WL.push_back(sr);
+}
+
RegionStoreSubRegionMap*
RegionStoreManager::getRegionStoreSubRegionMap(const GRState *state) {
RegionBindingsTy B = GetRegionBindings(state->getStore());
RegionStoreSubRegionMap *M = new RegionStoreSubRegionMap();
- llvm::SmallPtrSet<const MemRegion*, 10> Marked;
llvm::SmallVector<const SubRegion*, 10> WL;
for (RegionBindingsTy::iterator I=B.begin(), E=B.end(); I!=E; ++I)
- if (const SubRegion* R = dyn_cast<SubRegion>(I.getKey()))
- WL.push_back(R);
-
+ if (const SubRegion *R = dyn_cast<SubRegion>(I.getKey()))
+ M->process(WL, R);
+
RegionDefaultValue::MapTy DVM = state->get<RegionDefaultValue>();
for (RegionDefaultValue::MapTy::iterator I = DVM.begin(), E = DVM.end();
- I != E; ++I)
- if (const SubRegion* R = dyn_cast<SubRegion>(I.getKey()))
- WL.push_back(R);
+ I != E; ++I)
+ if (const SubRegion *R = dyn_cast<SubRegion>(I.getKey()))
+ M->process(WL, R);
// We also need to record in the subregion map "intermediate" regions that
// don't have direct bindings but are super regions of those that do.
while (!WL.empty()) {
const SubRegion *R = WL.back();
WL.pop_back();
-
- if (Marked.count(R))
- continue;
-
- const MemRegion *superR = R->getSuperRegion();
- if (M->add(superR, R))
- if (const SubRegion *sr = dyn_cast<SubRegion>(superR))
- WL.push_back(sr);
+ M->process(WL, R);
}
return M;
@@ -425,17 +438,20 @@
// Binding invalidation.
//===----------------------------------------------------------------------===//
-RegionBindingsTy
-RegionStoreManager::RemoveSubRegionBindings(RegionBindingsTy B,
- const MemRegion *R,
- RegionStoreSubRegionMap &M) {
+void
+RegionStoreManager::RemoveSubRegionBindings(RegionBindingsTy &B,
+ RegionDefaultValue::MapTy &DVM,
+ RegionDefaultValue::MapTy::Factory &DVMFactory,
+ const MemRegion *R,
+ RegionStoreSubRegionMap &M) {
RegionStoreSubRegionMap::iterator I, E;
for (llvm::tie(I, E) = M.begin_end(R); I != E; ++I)
- B = RemoveSubRegionBindings(B, *I, M);
+ RemoveSubRegionBindings(B, DVM, DVMFactory, *I, M);
- return RBFactory.Remove(B, R);
+ B = RBFactory.Remove(B, R);
+ DVM = DVMFactory.Remove(DVM, R);
}
@@ -448,15 +464,21 @@
// Strip away casts.
R = R->getBaseRegion();
- // Get the mapping of regions -> subregions.
- llvm::OwningPtr<RegionStoreSubRegionMap>
- SubRegions(getRegionStoreSubRegionMap(state));
-
// Remove the bindings to subregions.
- RegionBindingsTy B = GetRegionBindings(state->getStore());
- B = RemoveSubRegionBindings(B, R, *SubRegions.get());
- state = state->makeWithStore(B.getRoot());
-
+ {
+ // Get the mapping of regions -> subregions.
+ llvm::OwningPtr<RegionStoreSubRegionMap>
+ SubRegions(getRegionStoreSubRegionMap(state));
+
+ RegionBindingsTy B = GetRegionBindings(state->getStore());
+ RegionDefaultValue::MapTy DVM = state->get<RegionDefaultValue>();
+ RegionDefaultValue::MapTy::Factory &DVMFactory =
+ state->get_context<RegionDefaultValue>();
+
+ RemoveSubRegionBindings(B, DVM, DVMFactory, R, *SubRegions.get());
+ state = state->makeWithStore(B.getRoot())->set<RegionDefaultValue>(DVM);
+ }
+
if (!R->isBoundable())
return state;
@@ -975,7 +997,32 @@
ValMgr.getRegionValueSymbolValOrUnknown(R, RTy));
}
+std::pair<const GRState*, const MemRegion*>
+RegionStoreManager::GetLazyBinding(RegionBindingsTy B, const MemRegion *R) {
+ if (const nonloc::LazyCompoundVal *V =
+ dyn_cast_or_null<nonloc::LazyCompoundVal>(B.lookup(R)))
+ return std::make_pair(V->getState(), V->getRegion());
+
+ if (const ElementRegion *ER = dyn_cast<ElementRegion>(R)) {
+ const std::pair<const GRState *, const MemRegion *> &X =
+ GetLazyBinding(B, ER->getSuperRegion());
+
+ if (X.first)
+ return std::make_pair(X.first,
+ MRMgr.getElementRegionWithSuper(ER, X.second));
+ }
+ else if (const FieldRegion *FR = dyn_cast<FieldRegion>(R)) {
+ const std::pair<const GRState *, const MemRegion *> &X =
+ GetLazyBinding(B, FR->getSuperRegion());
+
+ if (X.first)
+ return std::make_pair(X.first,
+ MRMgr.getFieldRegionWithSuper(FR, X.second));
+ }
+
+ return std::make_pair((const GRState*) 0, (const MemRegion *) 0);
+}
SVal RegionStoreManager::RetrieveElement(const GRState* state,
const ElementRegion* R) {
@@ -1039,10 +1086,30 @@
if (V->isUnknownOrUndef())
return *V;
+ // Handle LazyCompoundVals below.
+ if (const nonloc::LazyCompoundVal *LVC =
+ dyn_cast<nonloc::LazyCompoundVal>(V)) {
+ return RetrieveElement(LVC->getState(),
+ MRMgr.getElementRegionWithSuper(R,
+ LVC->getRegion()));
+ }
+
// Other cases: give up.
return UnknownVal();
}
+ // Lazy binding?
+ const GRState *lazyBindingState = NULL;
+ const MemRegion *LazyBindingRegion = NULL;
+ llvm::tie(lazyBindingState, LazyBindingRegion) = GetLazyBinding(B, R);
+
+ if (lazyBindingState) {
+ assert(LazyBindingRegion && "Lazy-binding region not set");
+ return RetrieveElement(lazyBindingState,
+ cast<ElementRegion>(LazyBindingRegion));
+ }
+
+ // Default value cases.
#if 0
if (R->hasHeapStorage()) {
// FIXME: If the region has heap storage and we know nothing special
@@ -1093,12 +1160,25 @@
if (D->isZeroConstant())
return ValMgr.makeZeroVal(Ty);
+
+ if (const nonloc::LazyCompoundVal *LCV =
+ dyn_cast<nonloc::LazyCompoundVal>(D)) {
+ const FieldRegion *FR =
+ MRMgr.getFieldRegionWithSuper(R, LCV->getRegion());
+ return RetrieveField(LCV->getState(), FR);
+ }
if (D->isUnknown())
return *D;
assert(0 && "Unknown default value");
}
+
+ if (const SVal *V = B.lookup(superR)) {
+ // Handle LazyCompoundVals below.
+ if (isa<nonloc::CompoundVal>(*V))
+ break;
+ }
// If our super region is a field or element itself, walk up the region
// hierarchy to see if there is a default value installed in an ancestor.
@@ -1108,7 +1188,18 @@
}
break;
- }
+ }
+
+ // Lazy binding?
+ const GRState *lazyBindingState = NULL;
+ const MemRegion *LazyBindingRegion = NULL;
+ llvm::tie(lazyBindingState, LazyBindingRegion) = GetLazyBinding(B, R);
+
+ if (lazyBindingState) {
+ assert(LazyBindingRegion && "Lazy-binding region not set");
+ return RetrieveField(lazyBindingState,
+ cast<FieldRegion>(LazyBindingRegion));
+ }
#if HEAP_UNDEFINED
// FIXME: Is this correct? Should it be UnknownVal?
@@ -1206,7 +1297,7 @@
const RecordType* RT = T->getAsStructureType();
RecordDecl* RD = RT->getDecl();
assert(RD->isDefinition());
-
+#if USE_EXPLICIT_COMPOUND
llvm::ImmutableList<SVal> StructVal = getBasicVals().getEmptySValList();
// FIXME: We shouldn't use a std::vector. If RecordDecl doesn't have a
@@ -1223,11 +1314,14 @@
}
return ValMgr.makeCompoundVal(T, StructVal);
+#else
+ return ValMgr.makeLazyCompoundVal(state, R);
+#endif
}
SVal RegionStoreManager::RetrieveArray(const GRState *state,
const TypedRegion * R) {
-
+#if USE_EXPLICIT_COMPOUND
QualType T = R->getValueType(getContext());
ConstantArrayType* CAT = cast<ConstantArrayType>(T.getTypePtr());
@@ -1243,6 +1337,10 @@
}
return ValMgr.makeCompoundVal(T, ArrayVal);
+#else
+ assert(isa<ConstantArrayType>(R->getValueType(getContext())));
+ return ValMgr.makeLazyCompoundVal(state, R);
+#endif
}
SValuator::CastResult RegionStoreManager::CastRetrievedVal(SVal V,
@@ -1311,8 +1409,7 @@
// Perform the binding.
RegionBindingsTy B = GetRegionBindings(state->getStore());
- B = RBFactory.Add(B, R, V);
- return state->makeWithStore(B.getRoot());
+ return state->makeWithStore(RBFactory.Add(B, R, V).getRoot());
}
const GRState *RegionStoreManager::BindDecl(const GRState *state,
@@ -1375,6 +1472,11 @@
return state;
}
+ // Handle lazy compound values.
+ if (nonloc::LazyCompoundVal *LCV = dyn_cast<nonloc::LazyCompoundVal>(&Init))
+ return CopyLazyBindings(*LCV, state, R);
+
+ // Remaining case: explicit compound values.
nonloc::CompoundVal& CV = cast<nonloc::CompoundVal>(Init);
nonloc::CompoundVal::iterator VI = CV.begin(), VE = CV.end();
uint64_t i = 0;
@@ -1421,6 +1523,10 @@
if (!RD->isDefinition())
return state;
+ // Handle lazy compound values.
+ if (const nonloc::LazyCompoundVal *LCV = dyn_cast<nonloc::LazyCompoundVal>(&V))
+ return CopyLazyBindings(*LCV, state, R);
+
// We may get non-CompoundVal accidentally due to imprecise cast logic.
// Ignore them and kill the field values.
if (V.isUnknown() || !isa<nonloc::CompoundVal>(V))
@@ -1477,7 +1583,29 @@
const MemRegion* R, SVal V) {
return state->set<RegionDefaultValue>(R, V);
}
+
+const GRState*
+RegionStoreManager::CopyLazyBindings(nonloc::LazyCompoundVal V,
+ const GRState *state,
+ const TypedRegion *R) {
+ // Nuke the old bindings stemming from R.
+ RegionBindingsTy B = GetRegionBindings(state->getStore());
+ RegionDefaultValue::MapTy DVM = state->get<RegionDefaultValue>();
+ RegionDefaultValue::MapTy::Factory &DVMFactory =
+ state->get_context<RegionDefaultValue>();
+
+ llvm::OwningPtr<RegionStoreSubRegionMap>
+ SubRegions(getRegionStoreSubRegionMap(state));
+
+ // B and DVM are updated after the call to RemoveSubRegionBindings.
+ RemoveSubRegionBindings(B, DVM, DVMFactory, R, *SubRegions.get());
+
+ // Now copy the bindings. This amounts to just binding 'V' to 'R'. This
+ // results in a zero-copy algorithm.
+ return state->makeWithStore(RBFactory.Add(B, R, V).getRoot());
+}
+
//===----------------------------------------------------------------------===//
// State pruning.
//===----------------------------------------------------------------------===//
@@ -1666,6 +1794,9 @@
SymReaper.maybeDead(*SI);
}
+ // FIXME: Do a pass over nonloc::LazyCompoundVals and the symbols
+ // that they reference.
+
// Write the store back.
state.setStore(store);
Modified: cfe/trunk/lib/Analysis/SVals.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/SVals.cpp?rev=78268&r1=78267&r2=78268&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/SVals.cpp (original)
+++ cfe/trunk/lib/Analysis/SVals.cpp Wed Aug 5 20:20:57 2009
@@ -158,6 +158,14 @@
assert(false && "unhandled expansion case");
}
+const GRState *nonloc::LazyCompoundVal::getState() const {
+ return static_cast<const LazyCompoundValData*>(Data)->getState();
+}
+
+const TypedRegion *nonloc::LazyCompoundVal::getRegion() const {
+ return static_cast<const LazyCompoundValData*>(Data)->getRegion();
+}
+
//===----------------------------------------------------------------------===//
// Other Iterators.
//===----------------------------------------------------------------------===//
@@ -289,7 +297,13 @@
}
os << "}";
break;
- }
+ }
+ case nonloc::LazyCompoundValKind: {
+ const nonloc::LazyCompoundVal &C = *cast<nonloc::LazyCompoundVal>(this);
+ os << "lazyCompoundVal{" << (void*) C.getState() << ',' << C.getRegion()
+ << '}';
+ break;
+ }
default:
assert (false && "Pretty-printed not implemented for this NonLoc.");
break;
More information about the cfe-commits
mailing list