aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/Analysis/PathSensitive/BasicStore.h4
-rw-r--r--include/clang/Analysis/PathSensitive/GRState.h1
-rw-r--r--include/clang/Analysis/PathSensitive/Regions.h84
-rw-r--r--include/clang/Analysis/PathSensitive/Store.h3
-rw-r--r--lib/Analysis/BasicStore.cpp43
-rw-r--r--lib/Analysis/GRExprEngine.cpp2
-rw-r--r--lib/Analysis/Regions.cpp34
7 files changed, 143 insertions, 28 deletions
diff --git a/include/clang/Analysis/PathSensitive/BasicStore.h b/include/clang/Analysis/PathSensitive/BasicStore.h
index 88ac9ce381..b936e2ac4f 100644
--- a/include/clang/Analysis/PathSensitive/BasicStore.h
+++ b/include/clang/Analysis/PathSensitive/BasicStore.h
@@ -18,10 +18,12 @@
namespace llvm {
class llvm::BumpPtrAllocator;
+ class ASTContext;
}
namespace clang {
- StoreManager* CreateBasicStoreManager(llvm::BumpPtrAllocator& Alloc);
+ StoreManager* CreateBasicStoreManager(llvm::BumpPtrAllocator& Alloc,
+ ASTContext& Ctx);
}
#endif
diff --git a/include/clang/Analysis/PathSensitive/GRState.h b/include/clang/Analysis/PathSensitive/GRState.h
index d5eb55ab6d..c360da9a7c 100644
--- a/include/clang/Analysis/PathSensitive/GRState.h
+++ b/include/clang/Analysis/PathSensitive/GRState.h
@@ -304,6 +304,7 @@ public:
const GRState* getInitialState();
+ ASTContext& getContext() { return BasicVals.getContext(); }
BasicValueFactory& getBasicVals() { return BasicVals; }
const BasicValueFactory& getBasicVals() const { return BasicVals; }
SymbolManager& getSymbolManager() { return SymMgr; }
diff --git a/include/clang/Analysis/PathSensitive/Regions.h b/include/clang/Analysis/PathSensitive/Regions.h
index 9fd127c4a7..d62b033726 100644
--- a/include/clang/Analysis/PathSensitive/Regions.h
+++ b/include/clang/Analysis/PathSensitive/Regions.h
@@ -15,12 +15,94 @@
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/Casting.h"
#include "llvm/ADT/FoldingSet.h"
+#include "clang/Analysis/PathSensitive/SymbolManager.h"
#ifndef LLVM_CLANG_ANALYSIS_REGIONS_H
#define LLVM_CLANG_ANALYSIS_REGIONS_H
+namespace llvm {
+ class APSInt;
+}
+
namespace clang {
+class BasicValueFactory;
+
+
+//===----------------------------------------------------------------------===//
+// Region Extents.
+//===----------------------------------------------------------------------===//
+
+class RegionExtent {
+public:
+ enum Kind { Unknown = 0, Int = 0, Sym = 1 };
+
+protected:
+ const uintptr_t Raw;
+ RegionExtent(uintptr_t raw, Kind k) : Raw(raw | k) {}
+ uintptr_t getData() const { return Raw & ~0x1; }
+
+public:
+ // Folding-set profiling.
+ void Profile(llvm::FoldingSetNodeID& ID) const {
+ ID.AddPointer((void*) Raw);
+ }
+ // Comparing extents.
+ bool operator==(const RegionExtent& R) const {
+ return Raw == R.Raw;
+ }
+ bool operator!=(const RegionExtent& R) const {
+ return Raw != R.Raw;
+ }
+ // Implement isa<T> support.
+ Kind getKind() const { return Kind(Raw & 0x1); }
+ uintptr_t getRaw() const { return Raw; }
+
+ static inline bool classof(const RegionExtent*) {
+ return true;
+ }
+};
+
+class UnknownExtent : public RegionExtent {
+public:
+ UnknownExtent() : RegionExtent(0,Unknown) {}
+
+ // Implement isa<T> support.
+ static inline bool classof(const RegionExtent* E) {
+ return E->getRaw() == 0;
+ }
+};
+
+class IntExtent : public RegionExtent {
+public:
+ IntExtent(const llvm::APSInt& X) : RegionExtent((uintptr_t) &X, Int) {}
+
+ const llvm::APSInt& getInt() const {
+ return *((llvm::APSInt*) getData());
+ }
+
+ // Implement isa<T> support.
+ static inline bool classof(const RegionExtent* E) {
+ return E->getKind() == Int && E->getRaw() != 0;
+ }
+};
+
+class SymExtent : public RegionExtent {
+public:
+ SymExtent(SymbolID S) : RegionExtent(S.getNumber() << 1, Sym) {}
+
+ SymbolID getSymbol() const { return SymbolID(getData() >> 1); }
+
+ // Implement isa<T> support.
+ static inline bool classof(const RegionExtent* E) {
+ return E->getKind() == Sym;
+ }
+};
+
+//===----------------------------------------------------------------------===//
+// Regions.
+//===----------------------------------------------------------------------===//
+
class Region {
public:
enum Kind { Var = 0x0, Anon = 0x1 };
@@ -62,6 +144,8 @@ public:
const VarDecl* getDecl() const { return (const VarDecl*) getData(); }
operator const VarDecl*() const { return getDecl(); }
+ RegionExtent getExtent(BasicValueFactory& BV) const;
+
// Implement isa<T> support.
static inline bool classof(const Region* R) {
return R->getKind() == Region::Var;
diff --git a/include/clang/Analysis/PathSensitive/Store.h b/include/clang/Analysis/PathSensitive/Store.h
index be824e774f..42ee328f60 100644
--- a/include/clang/Analysis/PathSensitive/Store.h
+++ b/include/clang/Analysis/PathSensitive/Store.h
@@ -52,6 +52,9 @@ public:
virtual void print(Store store, std::ostream& Out,
const char* nl, const char *sep) = 0;
+
+ /// getExtent - Returns the size of the region in bits.
+ virtual RegionExtent getExtent(GRStateManager& SM, Region R) = 0;
};
} // end clang namespace
diff --git a/lib/Analysis/BasicStore.cpp b/lib/Analysis/BasicStore.cpp
index 2ed89c6f7d..c2482bcd3b 100644
--- a/lib/Analysis/BasicStore.cpp
+++ b/lib/Analysis/BasicStore.cpp
@@ -25,9 +25,12 @@ namespace {
class VISIBILITY_HIDDEN BasicStoreManager : public StoreManager {
typedef llvm::ImmutableMap<VarDecl*,RVal> VarBindingsTy;
VarBindingsTy::Factory VBFactory;
+ ASTContext& C;
public:
- BasicStoreManager(llvm::BumpPtrAllocator& A) : VBFactory(A) {}
+ BasicStoreManager(llvm::BumpPtrAllocator& A, ASTContext& c)
+ : VBFactory(A), C(c) {}
+
virtual ~BasicStoreManager() {}
virtual RVal GetRVal(Store St, LVal LV, QualType T);
@@ -51,13 +54,23 @@ public:
virtual void print(Store store, std::ostream& Out,
const char* nl, const char *sep);
+
+ virtual RegionExtent getExtent(GRStateManager& SM, Region R);
};
} // end anonymous namespace
-StoreManager* clang::CreateBasicStoreManager(llvm::BumpPtrAllocator& A) {
- return new BasicStoreManager(A);
+StoreManager* clang::CreateBasicStoreManager(llvm::BumpPtrAllocator& A,
+ ASTContext& C) {
+ return new BasicStoreManager(A, C);
+}
+
+RegionExtent BasicStoreManager::getExtent(GRStateManager& SM, Region R) {
+ if (VarRegion *VR = dyn_cast<VarRegion>(&R))
+ return VR->getExtent(SM.getBasicVals());
+
+ return UnknownExtent();
}
RVal BasicStoreManager::GetRVal(Store St, LVal LV, QualType T) {
@@ -75,30 +88,8 @@ RVal BasicStoreManager::GetRVal(Store St, LVal LV, QualType T) {
return T ? *T : UnknownVal();
}
- case lval::SymbolValKind: {
-
- // FIXME: This is a broken representation of memory, and is prone
- // to crashing the analyzer when addresses to symbolic values are
- // passed through casts. We need a better representation of symbolic
- // memory (or just memory in general); probably we should do this
- // as a plugin class (similar to GRTransferFuncs).
-
-#if 0
- const lval::SymbolVal& SV = cast<lval::SymbolVal>(LV);
- assert (T.getTypePtr());
-
- // Punt on "symbolic" function pointers.
- if (T->isFunctionType())
- return UnknownVal();
-
- if (T->isPointerType())
- return lval::SymbolVal(SymMgr.getContentsOfSymbol(SV.getSymbol()));
- else
- return nonlval::SymbolVal(SymMgr.getContentsOfSymbol(SV.getSymbol()));
-#endif
-
+ case lval::SymbolValKind:
return UnknownVal();
- }
case lval::ConcreteIntKind:
// Some clients may call GetRVal with such an option simply because
diff --git a/lib/Analysis/GRExprEngine.cpp b/lib/Analysis/GRExprEngine.cpp
index 93ea5251e8..a14695d67e 100644
--- a/lib/Analysis/GRExprEngine.cpp
+++ b/lib/Analysis/GRExprEngine.cpp
@@ -120,7 +120,7 @@ GRExprEngine::GRExprEngine(CFG& cfg, Decl& CD, ASTContext& Ctx,
G(CoreEngine.getGraph()),
Liveness(L),
Builder(NULL),
- StateMgr(G.getContext(), CreateBasicStoreManager(G.getAllocator()),
+ StateMgr(G.getContext(), CreateBasicStoreManager(G.getAllocator(), Ctx),
G.getAllocator(), G.getCFG(), L),
SymMgr(StateMgr.getSymbolManager()),
CurrentStmt(NULL),
diff --git a/lib/Analysis/Regions.cpp b/lib/Analysis/Regions.cpp
new file mode 100644
index 0000000000..b725316243
--- /dev/null
+++ b/lib/Analysis/Regions.cpp
@@ -0,0 +1,34 @@
+//==- Regions.cpp - Abstract memory locations ----------------------*- C++ -*-//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines Region and its subclasses. Regions represent abstract
+// memory locations.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Analysis/PathSensitive/Regions.h"
+#include "clang/Analysis/PathSensitive/BasicValueFactory.h"
+#include "clang/AST/ASTContext.h"
+
+using namespace clang;
+
+RegionExtent VarRegion::getExtent(BasicValueFactory& BV) const {
+ QualType T = getDecl()->getType();
+
+ // FIXME: Add support for VLAs. This may require passing in additional
+ // information, or tracking a different region type.
+ if (!T.getTypePtr()->isConstantSizeType())
+ return UnknownExtent();
+
+ ASTContext& C = BV.getContext();
+ assert (!T->isObjCInterfaceType()); // @interface not a possible VarDecl type.
+ assert (T != C.VoidTy); // void not a possible VarDecl type.
+ return IntExtent(BV.getValue(C.getTypeSize(T), C.VoidPtrTy));
+}
+