diff options
| author | Ted Kremenek <kremenek@apple.com> | 2009-01-30 00:08:43 +0000 |
|---|---|---|
| committer | Ted Kremenek <kremenek@apple.com> | 2009-01-30 00:08:43 +0000 |
| commit | 7594e2a59a5ffc4abd80fea5d00d9be2496fe3fa (patch) | |
| tree | 8d096fc1653230433bbf40fffd112e711d1d943e /clang/lib/Analysis/RegionStore.cpp | |
| parent | 711e882c1bc0a59893e491f114e8917607242ea5 (diff) | |
| download | bcm5719-llvm-7594e2a59a5ffc4abd80fea5d00d9be2496fe3fa.tar.gz bcm5719-llvm-7594e2a59a5ffc4abd80fea5d00d9be2496fe3fa.zip | |
Fix a couple bugs:
- NonLoc::MakeVal() would use sizeof(unsigned) (literally) instead of consulting
ASTContext for the size (in bits) of 'int'. While it worked, it was a
conflation of concepts and using ASTContext.IntTy is 100% correct.
- RegionStore::getSizeInElements() no longer assumes that a VarRegion has the
type "ConstantArray", and handles the case when uses use ordinary variables
as if they were arrays.
- Fixed ElementRegion::getRValueType() to just return the rvalue type of its
"array region" in the case the array didn't have ArrayType.
- All of this fixes <rdar://problem/6541136>
llvm-svn: 63347
Diffstat (limited to 'clang/lib/Analysis/RegionStore.cpp')
| -rw-r--r-- | clang/lib/Analysis/RegionStore.cpp | 29 |
1 files changed, 18 insertions, 11 deletions
diff --git a/clang/lib/Analysis/RegionStore.cpp b/clang/lib/Analysis/RegionStore.cpp index e50b0abb61e..8d36d10a8a5 100644 --- a/clang/lib/Analysis/RegionStore.cpp +++ b/clang/lib/Analysis/RegionStore.cpp @@ -403,20 +403,27 @@ SVal RegionStoreManager::getSizeInElements(const GRState* St, const MemRegion* R) { if (const VarRegion* VR = dyn_cast<VarRegion>(R)) { // Get the type of the variable. - QualType T = VR->getRValueType(getContext()); + QualType T = VR->getDesugaredRValueType(getContext()); - // It must be of array type. - const ConstantArrayType* CAT = cast<ConstantArrayType>(T.getTypePtr()); - - // return the size as signed integer. - return NonLoc::MakeVal(getBasicVals(), CAT->getSize(), false); + // FIXME: Handle variable-length arrays. + if (isa<VariableArrayType>(T)) + return UnknownVal(); + + if (const ConstantArrayType* CAT = dyn_cast<ConstantArrayType>(T)) { + // return the size as signed integer. + return NonLoc::MakeVal(getBasicVals(), CAT->getSize(), false); + } + + // Clients can use ordinary variables as if they were arrays. These + // essentially are arrays of size 1. + return NonLoc::MakeIntVal(getBasicVals(), 1, false); } if (const StringRegion* SR = dyn_cast<StringRegion>(R)) { const StringLiteral* Str = SR->getStringLiteral(); // We intentionally made the size value signed because it participates in // operations with signed indices. - return NonLoc::MakeVal(getBasicVals(), Str->getByteLength() + 1, false); + return NonLoc::MakeIntVal(getBasicVals(), Str->getByteLength()+1, false); } if (const AnonTypedRegion* ATR = dyn_cast<AnonTypedRegion>(R)) { @@ -880,8 +887,8 @@ const GRState* RegionStoreManager::BindArray(const GRState* St, // When we are binding the whole array, it always has default value 0. GRStateRef state(St, StateMgr); - St = state.set<RegionDefaultValue>(R, NonLoc::MakeVal(getBasicVals(), 0, - false)); + St = state.set<RegionDefaultValue>(R, NonLoc::MakeIntVal(getBasicVals(), 0, + false)); Store store = St->getStore(); @@ -961,8 +968,8 @@ RegionStoreManager::BindStruct(const GRState* St, const TypedRegion* R, SVal V){ // struct decl. In this case, mark the region as having default value. if (VI == VE) { GRStateRef state(St, StateMgr); - St = state.set<RegionDefaultValue>(R, NonLoc::MakeVal(getBasicVals(), 0, - false)); + const NonLoc& Idx = NonLoc::MakeIntVal(getBasicVals(), 0, false); + St = state.set<RegionDefaultValue>(R, Idx); break; } |

