diff options
author | Ted Kremenek <kremenek@apple.com> | 2009-03-04 22:56:43 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2009-03-04 22:56:43 +0000 |
commit | d104a09d30ec35cb67931051d5d0c1ff2ee2d697 (patch) | |
tree | a0520ef81be44ffc8c9c2c8f14a099af2105b9ee /lib/Analysis/CFRefCount.cpp | |
parent | 1b9b883a95215e38e153d253a46a2a2fcac25896 (diff) |
Add prototype support for invalidating fields for structures passed-by-reference
to unknown functions. Most of this logic should be eventually moved to
RegionStore and be made lazy.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@66094 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis/CFRefCount.cpp')
-rw-r--r-- | lib/Analysis/CFRefCount.cpp | 89 |
1 files changed, 71 insertions, 18 deletions
diff --git a/lib/Analysis/CFRefCount.cpp b/lib/Analysis/CFRefCount.cpp index 5e1857168d..7e6507cbe5 100644 --- a/lib/Analysis/CFRefCount.cpp +++ b/lib/Analysis/CFRefCount.cpp @@ -1650,28 +1650,81 @@ void CFRefCount::EvalSummary(ExplodedNodeSet<GRState>& Dst, R = dyn_cast<TypedRegion>(ATR->getSuperRegion()); } - if (R && R->isBoundable(Ctx)) { + if (R) { // Is the invalidated variable something that we were tracking? SymbolRef Sym = state.GetSValAsScalarOrLoc(R).getAsLocSymbol(); - if (Sym.isValid()) - state = state.remove<RefBindings>(Sym); - // Set the value of the variable to be a conjured symbol. - unsigned Count = Builder.getCurrentBlockCount(); - QualType T = R->getRValueType(Ctx); + // Remove any existing reference-count binding. + if (Sym.isValid()) state = state.remove<RefBindings>(Sym); - // FIXME: handle structs. - if (Loc::IsLocType(T) || (T->isIntegerType() && T->isScalarType())) { - SymbolRef NewSym = - Eng.getSymbolManager().getConjuredSymbol(*I, T, Count); - - state = state.BindLoc(Loc::MakeVal(R), - Loc::IsLocType(T) - ? cast<SVal>(loc::SymbolVal(NewSym)) - : cast<SVal>(nonloc::SymbolVal(NewSym))); - } - else { - state = state.BindLoc(*MR, UnknownVal()); + if (R->isBoundable(Ctx)) { + // Set the value of the variable to be a conjured symbol. + unsigned Count = Builder.getCurrentBlockCount(); + QualType T = R->getRValueType(Ctx); + + if (Loc::IsLocType(T) || (T->isIntegerType() && T->isScalarType())) { + SymbolRef NewSym = + Eng.getSymbolManager().getConjuredSymbol(*I, T, Count); + + state = state.BindLoc(Loc::MakeVal(R), + Loc::IsLocType(T) + ? cast<SVal>(loc::SymbolVal(NewSym)) + : cast<SVal>(nonloc::SymbolVal(NewSym))); + } + else if (const RecordType *RT = T->getAsStructureType()) { + // Handle structs in a not so awesome way. Here we just + // eagerly bind new symbols to the fields. In reality we + // should have the store manager handle this. The idea is just + // to prototype some basic functionality here. All of this logic + // should one day soon just go away. + const RecordDecl *RD = RT->getDecl()->getDefinition(Ctx); + + // No record definition. There is nothing we can do. + if (!RD) + continue; + + MemRegionManager &MRMgr = state.getManager().getRegionManager(); + + // Iterate through the fields and construct new symbols. + for (RecordDecl::field_iterator FI=RD->field_begin(), + FE=RD->field_end(); FI!=FE; ++FI) { + + // For now just handle scalar fields. + FieldDecl *FD = *FI; + QualType FT = FD->getType(); + + if (Loc::IsLocType(FT) || + (FT->isIntegerType() && FT->isScalarType())) { + + // Tag the symbol with the field decl so that we generate + // a unique symbol. + SymbolRef NewSym = + Eng.getSymbolManager().getConjuredSymbol(*I, FT, Count, FD); + + // Create a region. + // FIXME: How do we handle 'typedefs' in TypeViewRegions? + // e.g.: + // typedef struct *s foo; + // + // ((foo) x)->f vs. x->f + // + // The cast will add a ViewTypeRegion. Probably RegionStore + // needs to reason about typedefs explicitly when binding + // fields and elements. + // + const FieldRegion* FR = MRMgr.getFieldRegion(FD, R); + + state = state.BindLoc(Loc::MakeVal(FR), + Loc::IsLocType(FT) + ? cast<SVal>(loc::SymbolVal(NewSym)) + : cast<SVal>(nonloc::SymbolVal(NewSym))); + } + } + } + else { + // Just blast away other values. + state = state.BindLoc(*MR, UnknownVal()); + } } } else |