From: Zhongxing Xu Date: Wed, 6 May 2009 11:51:48 +0000 (+0000) Subject: Improve RegionStoreManager::getSizeInElements() X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=41fd01809e67eb1bd24b4ea2d8047078104249e6;p=clang 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 043fc95e08..5f987fdf27 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 @@ private: // 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 @@ StoreManager* clang::CreateRegionStoreManager(GRStateManager& StMgr) { 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(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 @@ SVal RegionStoreManager::getSizeInElements(const GRState* St, // 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(VR); + + if (CastTy) { + QualType EleTy =cast(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 @@ static bool isSmallerThan(QualType T1, QualType T2) { RegionStoreManager::CastResult RegionStoreManager::CastRegion(const GRState* state, const MemRegion* R, - QualType CastToTy) { + QualType CastToTy) { ASTContext& Ctx = StateMgr.getContext(); diff --git a/test/Analysis/xfail-no-outofbounds.c b/test/Analysis/xfail-no-outofbounds.c index e5c21c5b81..f2ee732c25 100644 --- a/test/Analysis/xfail-no-outofbounds.c +++ b/test/Analysis/xfail-no-outofbounds.c @@ -1,5 +1,5 @@ // RUN: clang-cc -checker-cfref -analyze -analyzer-store=region -verify %s -// XFAIL + void f() { long x = 0; char *y = (char*) &x;