From: Zhongxing Xu Date: Fri, 6 Feb 2009 08:44:27 +0000 (+0000) Subject: Create ElementRegion when the base is SymbolicRegion. This is like what we do X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=a48f7378a05095595d0f6a9c11fc8141e7a5ea61;p=clang Create ElementRegion when the base is SymbolicRegion. This is like what we do for FieldRegion. This enables us to track more values. Simplify SymbolicRegion::getRValueType(). We assume the symbol always has pointer type. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@63928 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Analysis/MemRegion.cpp b/lib/Analysis/MemRegion.cpp index e41c5f937b..779f651edb 100644 --- a/lib/Analysis/MemRegion.cpp +++ b/lib/Analysis/MemRegion.cpp @@ -114,18 +114,14 @@ void ElementRegion::Profile(llvm::FoldingSetNodeID& ID) const { QualType SymbolicRegion::getRValueType(ASTContext& C) const { const SymbolData& data = SymMgr.getSymbolData(sym); - // FIXME: We could use the SymbolManager::getType() directly. But that - // would hide the assumptions we made here. What is the type of a symbolic - // region is unclear for other cases. + // Get the type of the symbol. + QualType T = data.getType(C); - // For now we assume the symbol is a typed region rvalue. - const TypedRegion* R - = cast(cast(data).getRegion()); - - // Assume the region rvalue has a pointer type, only then we could have a - // symbolic region associated with it. - PointerType* PTy = cast(R->getRValueType(C).getTypePtr()); + // Only when the symbol has pointer type it can have a symbolic region + // associated with it. + PointerType* PTy = cast(T.getTypePtr()->getDesugaredType()); + // The type of the symbolic region is the pointee type of the symbol. return PTy->getPointeeType(); } diff --git a/lib/Analysis/RegionStore.cpp b/lib/Analysis/RegionStore.cpp index e640087acb..93b55255d5 100644 --- a/lib/Analysis/RegionStore.cpp +++ b/lib/Analysis/RegionStore.cpp @@ -339,15 +339,20 @@ SVal RegionStoreManager::getLValueField(const GRState* St, SVal Base, SVal RegionStoreManager::getLValueElement(const GRState* St, SVal Base, SVal Offset) { - if (Base.isUnknownOrUndef() || isa(Base)) + if (Base.isUnknownOrUndef()) return Base; // Only handle integer offsets... for now. if (!isa(Offset)) return UnknownVal(); - const TypedRegion *BaseRegion = - cast(cast(Base).getRegion()); + const TypedRegion* BaseRegion = 0; + + if (isa(Base)) + BaseRegion = MRMgr.getSymbolicRegion(cast(Base).getSymbol(), + StateMgr.getSymbolManager()); + else + BaseRegion = cast(cast(Base).getRegion()); // Pointer of any type can be cast and used as array base. const ElementRegion *ElemR = dyn_cast(BaseRegion); @@ -476,6 +481,12 @@ SVal RegionStoreManager::getSizeInElements(const GRState* St, return UnknownVal(); } + if (const SymbolicRegion* SR = dyn_cast(R)) { + // FIXME: Unsupported yet. + SR = 0; + return UnknownVal(); + } + assert(0 && "Other regions are not supported yet."); return UnknownVal(); } diff --git a/test/Analysis/null-deref-ps.c b/test/Analysis/null-deref-ps.c index 6daedf0f93..0c23690d45 100644 --- a/test/Analysis/null-deref-ps.c +++ b/test/Analysis/null-deref-ps.c @@ -212,3 +212,12 @@ void f12(HF12ITEM i, char *q) { *p = 1; // no-warning } +// Exercise ElementRegion with SymbolicRegion as super region. +void foo(int* p) { + int *x; + int a; + if (p[0] == 1) + x = &a; + if (p[0] == 1) + *x; // no-warning +}