Improve RegionStoreManager::getSizeInElements()
- add a static function getTypeWidth(), which computes the width of a type
with the help of TargetInfo.
- no-outofbounds.c now passes for region store.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@71080 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Analysis/RegionStore.cpp b/lib/Analysis/RegionStore.cpp
index 043fc95..5f987fd 100644
--- a/lib/Analysis/RegionStore.cpp
+++ b/lib/Analysis/RegionStore.cpp
@@ -18,6 +18,7 @@
#include "clang/Analysis/PathSensitive/GRState.h"
#include "clang/Analysis/PathSensitive/GRStateTrait.h"
#include "clang/Analysis/Analyses/LiveVariables.h"
+#include "clang/Basic/TargetInfo.h"
#include "llvm/ADT/ImmutableMap.h"
#include "llvm/ADT/ImmutableList.h"
@@ -296,6 +297,7 @@
// Utility methods.
BasicValueFactory& getBasicVals() { return StateMgr.getBasicVals(); }
ASTContext& getContext() { return StateMgr.getContext(); }
+ TargetInfo& getTargetInfo() { return getContext().getTargetInfo(); }
SymbolManager& getSymbolManager() { return StateMgr.getSymbolManager(); }
const GRState* AddRegionView(const GRState* St,
@@ -310,6 +312,45 @@
return new RegionStoreManager(StMgr);
}
+// getTypeWidth - compute the width of the type. Should pass in
+// canonical type.
+static unsigned getTypeWidth(ASTContext& Ctx, QualType T) {
+ TargetInfo& Target = Ctx.getTargetInfo();
+ QualType CanT = Ctx.getCanonicalType(T);
+
+ if (CanT->isPointerType())
+ return Target.getPointerWidth(0);
+
+ if (CanT->isCharType())
+ return Target.getCharWidth();
+
+ if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanT)) {
+ switch (BT->getKind()) {
+ case BuiltinType::Char_U:
+ case BuiltinType::UChar:
+ case BuiltinType::Char_S:
+ case BuiltinType::SChar:
+ return Target.getCharWidth();
+
+ case BuiltinType::UShort:
+ case BuiltinType::Short:
+ return Target.getShortWidth();
+
+ case BuiltinType::UInt:
+ case BuiltinType::Int:
+ return Target.getIntWidth();
+
+ case BuiltinType::ULong:
+ case BuiltinType::Long:
+ return Target.getLongWidth();
+ default:
+ assert(0 && "Unprocessed builtin type.");
+ }
+ }
+
+ assert(0 && "Unprocessed type.");
+}
+
SubRegionMap* RegionStoreManager::getSubRegionMap(const GRState *state) {
RegionBindingsTy B = GetRegionBindings(state->getStore());
RegionStoreSubRegionMap *M = new RegionStoreSubRegionMap();
@@ -503,7 +544,17 @@
// If the VarRegion is cast to other type, compute the size with respect to
// that type.
-
+ GRStateRef state(St, StateMgr);
+ const QualType* CastTy = state.get<RegionCasts>(VR);
+
+ if (CastTy) {
+ QualType EleTy =cast<PointerType>(CastTy->getTypePtr())->getPointeeType();
+ QualType VarTy = VR->getRValueType(getContext());
+ unsigned EleWidth = getTypeWidth(getContext(), EleTy);
+ unsigned VarWidth = getTypeWidth(getContext(), VarTy);
+ return NonLoc::MakeIntVal(getBasicVals(), VarWidth / EleWidth, false);
+ }
+
// Clients can use ordinary variables as if they were arrays. These
// essentially are arrays of size 1.
return NonLoc::MakeIntVal(getBasicVals(), 1, false);
@@ -613,7 +664,7 @@
RegionStoreManager::CastResult
RegionStoreManager::CastRegion(const GRState* state, const MemRegion* R,
- QualType CastToTy) {
+ QualType CastToTy) {
ASTContext& Ctx = StateMgr.getContext();