[cfe-commits] r59382 - in /cfe/trunk: include/clang/Analysis/PathSensitive/MemRegion.h include/clang/Analysis/PathSensitive/Store.h lib/Analysis/BasicStore.cpp lib/Analysis/GRExprEngine.cpp lib/Analysis/MemRegion.cpp lib/Analysis/RegionStore.cpp
Zhongxing Xu
xuzhongxing at gmail.com
Sat Nov 15 20:07:27 PST 2008
Author: zhongxingxu
Date: Sat Nov 15 22:07:26 2008
New Revision: 59382
URL: http://llvm.org/viewvc/llvm-project?rev=59382&view=rev
Log:
Enhances SCA to process untyped region to typed region conversion.
- RegionView and RegionViewMap is introduced to assist back-mapping from
super region to subregions.
- GDM is used to carry RegionView information.
- AnonTypedRegion is added to represent a typed region introduced by pointer
casting. Later AnonTypedRegion can be used in other similar cases, e.g.,
malloc()'ed region.
- The specific conversion is delegated to store manager.
Modified:
cfe/trunk/include/clang/Analysis/PathSensitive/MemRegion.h
cfe/trunk/include/clang/Analysis/PathSensitive/Store.h
cfe/trunk/lib/Analysis/BasicStore.cpp
cfe/trunk/lib/Analysis/GRExprEngine.cpp
cfe/trunk/lib/Analysis/MemRegion.cpp
cfe/trunk/lib/Analysis/RegionStore.cpp
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=59382&r1=59381&r2=59382&view=diff
==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/MemRegion.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/MemRegion.h Sat Nov 15 22:07:26 2008
@@ -23,6 +23,8 @@
#include "clang/AST/ASTContext.h"
#include "llvm/Support/Casting.h"
#include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/ImmutableList.h"
+#include "llvm/ADT/ImmutableMap.h"
#include "llvm/Support/Allocator.h"
#include <string>
@@ -42,12 +44,13 @@
BEG_TYPED_REGIONS,
CompoundLiteralRegionKind,
StringRegionKind, ElementRegionKind,
+ AnonTypedRegionKind,
+ AnonPointeeRegionKind,
// Decl Regions.
BEG_DECL_REGIONS,
VarRegionKind, FieldRegionKind,
ObjCIvarRegionKind, ObjCObjectRegionKind,
END_DECL_REGIONS,
- AnonPointeeRegionKind,
END_TYPED_REGIONS };
private:
const Kind kind;
@@ -201,6 +204,32 @@
}
};
+class AnonTypedRegion : public TypedRegion {
+ friend class MemRegionManager;
+
+ QualType T;
+
+ AnonTypedRegion(QualType t, const MemRegion* sreg)
+ : TypedRegion(sreg, AnonTypedRegionKind), T(t) {}
+
+ static void ProfileRegion(llvm::FoldingSetNodeID& ID, QualType T,
+ const MemRegion* superRegion);
+
+public:
+
+ QualType getType(ASTContext& C) const {
+ return T;
+ }
+
+ void Profile(llvm::FoldingSetNodeID& ID) const {
+ ProfileRegion(ID, T, superRegion);
+ }
+
+ static bool classof(const MemRegion* R) {
+ return R->getKind() == AnonTypedRegionKind;
+ }
+};
+
/// AnonPointeeRegion - anonymous regions pointed-to by pointer function
/// parameters or pointer globals. In RegionStoreManager, we assume pointer
/// parameters or globals point at some anonymous region. Such regions are not
@@ -494,7 +523,7 @@
MemSpaceRegion* stack;
MemSpaceRegion* heap;
MemSpaceRegion* unknown;
-
+
public:
MemRegionManager(llvm::BumpPtrAllocator& a)
: A(a), globals(0), stack(0), heap(0) {}
@@ -559,10 +588,12 @@
ObjCIvarRegion* getObjCIvarRegion(const ObjCIvarDecl* ivd,
const MemRegion* superRegion);
+ AnonTypedRegion* getAnonTypedRegion(QualType t, const MemRegion* superRegion);
+
AnonPointeeRegion* getAnonPointeeRegion(const VarDecl* d);
bool hasStackStorage(const MemRegion* R);
-
+
private:
MemSpaceRegion* LazyAllocate(MemSpaceRegion*& region);
};
Modified: cfe/trunk/include/clang/Analysis/PathSensitive/Store.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathSensitive/Store.h?rev=59382&r1=59381&r2=59382&view=diff
==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/Store.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/Store.h Sat Nov 15 22:07:26 2008
@@ -80,6 +80,9 @@
/// ArrayToPointer - Used by GRExprEngine::VistCast to handle implicit
/// conversions between arrays and pointers.
virtual SVal ArrayToPointer(SVal Array) = 0;
+
+ virtual const GRState* CastRegion(const GRState* St, SVal VoidPtr,
+ QualType CastToTy, Stmt* CastE) = 0;
/// getSelfRegion - Returns the region for the 'self' (Objective-C) or
/// 'this' object (C++). When used when analyzing a normal function this
Modified: cfe/trunk/lib/Analysis/BasicStore.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/BasicStore.cpp?rev=59382&r1=59381&r2=59382&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/BasicStore.cpp (original)
+++ cfe/trunk/lib/Analysis/BasicStore.cpp Sat Nov 15 22:07:26 2008
@@ -65,6 +65,12 @@
/// ArrayToPointer - Used by GRExprEngine::VistCast to handle implicit
/// conversions between arrays and pointers.
SVal ArrayToPointer(SVal Array) { return Array; }
+
+ const GRState* CastRegion(const GRState* St, SVal VoidPtr, QualType CastToTy,
+ Stmt* CastE) {
+ return St;
+ }
+
/// getSelfRegion - Returns the region for the 'self' (Objective-C) or
/// 'this' object (C++). When used when analyzing a normal function this
Modified: cfe/trunk/lib/Analysis/GRExprEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/GRExprEngine.cpp?rev=59382&r1=59381&r2=59382&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/GRExprEngine.cpp (original)
+++ cfe/trunk/lib/Analysis/GRExprEngine.cpp Sat Nov 15 22:07:26 2008
@@ -1692,6 +1692,21 @@
continue;
}
+ // Check for casts from AllocaRegion pointer to typed pointer.
+ if (isa<loc::MemRegionVal>(V)) {
+ assert(Loc::IsLocType(T));
+ assert(Loc::IsLocType(ExTy));
+
+ // Delegate to store manager.
+ const GRState* NewSt = getStoreManager().CastRegion(St, V, T, CastE);
+
+ // If no new region is created, fall through to the default case.
+ if (NewSt != St) {
+ MakeNode(Dst, CastE, N, NewSt);
+ continue;
+ }
+ }
+
// All other cases.
MakeNode(Dst, CastE, N, BindExpr(St, CastE, EvalCast(V, CastE->getType())));
}
Modified: cfe/trunk/lib/Analysis/MemRegion.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/MemRegion.cpp?rev=59382&r1=59381&r2=59382&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/MemRegion.cpp (original)
+++ cfe/trunk/lib/Analysis/MemRegion.cpp Sat Nov 15 22:07:26 2008
@@ -44,6 +44,13 @@
ProfileRegion(ID, Ex, Cnt);
}
+void AnonTypedRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, QualType T,
+ const MemRegion* superRegion) {
+ ID.AddInteger((unsigned) AnonTypedRegionKind);
+ ID.Add(T);
+ ID.AddPointer(superRegion);
+}
+
QualType AnonPointeeRegion::getType(ASTContext& C) const {
QualType T = C.getCanonicalType(Pointer->getType());
PointerType* PTy = cast<PointerType>(T.getTypePtr());
@@ -110,7 +117,7 @@
ArrayType* AT = cast<ArrayType>(T.getTypePtr());
return AT->getElementType();
}
- else if (isa<AllocaRegion>(superRegion)) {
+ else if (isa<AnonTypedRegion>(superRegion)) {
PointerType* PtrT = cast<PointerType>(T.getTypePtr());
QualType PTy = PtrT->getPointeeType();
return C.getCanonicalType(PTy);
@@ -369,6 +376,23 @@
return R;
}
+AnonTypedRegion*
+MemRegionManager::getAnonTypedRegion(QualType t, const MemRegion* superRegion) {
+ llvm::FoldingSetNodeID ID;
+ AnonTypedRegion::ProfileRegion(ID, t, superRegion);
+
+ void* InsertPos;
+ MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
+ AnonTypedRegion* R = cast_or_null<AnonTypedRegion>(data);
+
+ if (!R) {
+ R = (AnonTypedRegion*) A.Allocate<AnonTypedRegion>();
+ new (R) AnonTypedRegion(t, superRegion);
+ Regions.InsertNode(R, InsertPos);
+ }
+
+ return R;
+}
AnonPointeeRegion* MemRegionManager::getAnonPointeeRegion(const VarDecl* d) {
llvm::FoldingSetNodeID ID;
Modified: cfe/trunk/lib/Analysis/RegionStore.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/RegionStore.cpp?rev=59382&r1=59381&r2=59382&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/RegionStore.cpp (original)
+++ cfe/trunk/lib/Analysis/RegionStore.cpp Sat Nov 15 22:07:26 2008
@@ -16,26 +16,46 @@
//===----------------------------------------------------------------------===//
#include "clang/Analysis/PathSensitive/MemRegion.h"
#include "clang/Analysis/PathSensitive/GRState.h"
+#include "clang/Analysis/PathSensitive/GRStateTrait.h"
#include "clang/Analysis/Analyses/LiveVariables.h"
#include "llvm/ADT/ImmutableMap.h"
+#include "llvm/ADT/ImmutableList.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/Compiler.h"
using namespace clang;
typedef llvm::ImmutableMap<const MemRegion*, SVal> RegionBindingsTy;
+typedef llvm::ImmutableList<const MemRegion*> RegionViewTy;
+typedef llvm::ImmutableMap<const MemRegion*, RegionViewTy> RegionViewMapTy;
+
+static int RegionViewMapTyIndex = 0;
+
+namespace clang {
+template<> struct GRStateTrait<RegionViewMapTy>
+ : public GRStatePartialTrait<RegionViewMapTy> {
+ static void* GDMIndex() { return &RegionViewMapTyIndex; }
+};
+}
namespace {
class VISIBILITY_HIDDEN RegionStoreManager : public StoreManager {
RegionBindingsTy::Factory RBFactory;
+ RegionViewTy::Factory RVFactory;
+ RegionViewMapTy::Factory RVMFactory;
+
GRStateManager& StateMgr;
MemRegionManager MRMgr;
public:
RegionStoreManager(GRStateManager& mgr)
- : StateMgr(mgr), MRMgr(StateMgr.getAllocator()) {}
+ : RBFactory(mgr.getAllocator()),
+ RVFactory(mgr.getAllocator()),
+ RVMFactory(mgr.getAllocator()),
+ StateMgr(mgr),
+ MRMgr(StateMgr.getAllocator()) {}
virtual ~RegionStoreManager() {}
@@ -62,6 +82,9 @@
SVal ArrayToPointer(SVal Array);
+ const GRState* CastRegion(const GRState* St, SVal VoidPtr,
+ QualType CastToTy, Stmt* CastE);
+
SVal Retrieve(Store S, Loc L, QualType T = QualType());
Store Bind(Store St, Loc LV, SVal V);
@@ -112,6 +135,9 @@
// Utility methods.
BasicValueFactory& getBasicVals() { return StateMgr.getBasicVals(); }
ASTContext& getContext() { return StateMgr.getContext(); }
+
+ const GRState* AddRegionView(const GRState* St,
+ const MemRegion* View, const MemRegion* Base);
};
} // end anonymous namespace
@@ -238,6 +264,30 @@
return loc::MemRegionVal(ER);
}
+const GRState* RegionStoreManager::CastRegion(const GRState* St,
+ SVal VoidPtr,
+ QualType CastToTy,
+ Stmt* CastE) {
+ if (const AllocaRegion* AR =
+ dyn_cast<AllocaRegion>(cast<loc::MemRegionVal>(VoidPtr).getRegion())) {
+
+ // Create a new region to attach type information to it.
+ const AnonTypedRegion* TR = MRMgr.getAnonTypedRegion(CastToTy, AR);
+
+ // Get the pointer to the first element.
+ nonloc::ConcreteInt Idx(getBasicVals().getZeroWithPtrWidth(false));
+ const ElementRegion* ER = MRMgr.getElementRegion(Idx, TR);
+
+ St = StateMgr.BindExpr(St, CastE, loc::MemRegionVal(ER));
+
+ // Add a RegionView to base region.
+ return AddRegionView(St, TR, AR);
+ }
+
+ // Default case.
+ return St;
+}
+
SVal RegionStoreManager::Retrieve(Store S, Loc L, QualType T) {
assert(!isa<UnknownVal>(L) && "location unknown");
assert(!isa<UndefinedVal>(L) && "location undefined");
@@ -600,3 +650,19 @@
return store;
}
+
+const GRState* RegionStoreManager::AddRegionView(const GRState* St,
+ const MemRegion* View,
+ const MemRegion* Base) {
+ GRStateRef state(St, StateMgr);
+
+ // First, retrieve the region view of the base region.
+ RegionViewMapTy::data_type* d = state.get<RegionViewMapTy>(Base);
+ RegionViewTy L = d ? *d : RVFactory.GetEmptyList();
+
+ // Now add View to the region view.
+ L = RVFactory.Add(View, L);
+
+ // Create a new state with the new region view.
+ return state.set<RegionViewMapTy>(Base, L);
+}
More information about the cfe-commits
mailing list