mirror of
https://github.com/intel/llvm.git
synced 2026-01-30 14:07:28 +08:00
Added 'extents' for Regions.
Added 'getExtent()' to StoreManager. Implemented 'getExtent()' for BasicStoreManager. llvm-svn: 55321
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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; }
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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),
|
||||
|
||||
34
clang/lib/Analysis/Regions.cpp
Normal file
34
clang/lib/Analysis/Regions.cpp
Normal file
@@ -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));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user