Fix failure reported by Sebastian of test/Analysis/ptr-arith.c when the target

is 64-bit. I used his suggestion of doing a direct bitwidth/signedness
conversion of the 'offset' instead of just changing the sign. For more
information, see:

http://lists.cs.uiuc.edu/pipermail/cfe-dev/2009-March/004587.html

llvm-svn: 66892
This commit is contained in:
Ted Kremenek 2009-03-13 15:35:24 +00:00
parent 201217324a
commit ec94f08dce
3 changed files with 20 additions and 15 deletions

View File

@ -76,16 +76,18 @@ public:
const llvm::APSInt& getValue(uint64_t X, unsigned BitWidth, bool isUnsigned);
const llvm::APSInt& getValue(uint64_t X, QualType T);
const llvm::APSInt& ConvertSignedness(const llvm::APSInt& To,
const llvm::APSInt& From) {
assert(To.getBitWidth() == From.getBitWidth());
// Same sign? Just return.
if (To.isUnsigned() == From.isUnsigned())
/// Convert - Create a new persistent APSInt with the same value as 'From'
/// but with the bitwidth and signeness of 'To'.
const llvm::APSInt& Convert(const llvm::APSInt& To,
const llvm::APSInt& From) {
if (To.isUnsigned() == From.isUnsigned() &&
To.getBitWidth() == From.getBitWidth())
return From;
// Convert!
return getValue(llvm::APSInt((llvm::APInt&) From, To.isUnsigned()));
return getValue(From.getSExtValue(),
To.getBitWidth(),
To.isUnsigned());
}
const llvm::APSInt& getIntValue(uint64_t X, bool isUnsigned) {

View File

@ -642,12 +642,13 @@ SVal RegionStoreManager::EvalBinOp(BinaryOperator::Opcode Op, Loc L, NonLoc R) {
// Only support concrete integer indexes for now.
if (Base && Offset) {
// For now, convert the signedness of offset in case it doesn't match.
const llvm::APSInt &I =
getBasicVals().ConvertSignedness(Base->getValue(), Offset->getValue());
nonloc::ConcreteInt OffsetConverted(I);
SVal NewIdx = Base->EvalBinOp(getBasicVals(), Op, OffsetConverted);
// FIXME: For now, convert the signedness and bitwidth of offset in case
// they don't match. This can result from pointer arithmetic. In reality,
// we should figure out what are the proper semantics and implement them.
//
nonloc::ConcreteInt OffConverted(getBasicVals().Convert(Base->getValue(),
Offset->getValue()));
SVal NewIdx = Base->EvalBinOp(getBasicVals(), Op, OffConverted);
const MemRegion* NewER = MRMgr.getElementRegion(NewIdx,
ER->getArrayRegion());
return Loc::MakeVal(NewER);

View File

@ -1,4 +1,6 @@
// RUN: clang -analyze -checker-simple -analyzer-store=region -verify %s
// RUN: clang -analyze -checker-simple -analyzer-store=region -verify %s &&
// RUN: clang -analyze -checker-cfref -analyzer-store=region -verify -triple x86_64-apple-darwin9 %s &&
// RUN: clang -analyze -checker-cfref -analyzer-store=region -verify -triple i686-apple-darwin9 %s
void f1() {
int a[10];