From: Ted Kremenek Date: Fri, 13 Mar 2009 15:35:24 +0000 (+0000) Subject: Fix failure reported by Sebastian of test/Analysis/ptr-arith.c when the target X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=610e81d6b7248ce4be4be2252b03a5d4052c9835;p=clang 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 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@66892 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Analysis/PathSensitive/BasicValueFactory.h b/include/clang/Analysis/PathSensitive/BasicValueFactory.h index 18ae1d88e4..c0a28c3fd1 100644 --- a/include/clang/Analysis/PathSensitive/BasicValueFactory.h +++ b/include/clang/Analysis/PathSensitive/BasicValueFactory.h @@ -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) { diff --git a/lib/Analysis/RegionStore.cpp b/lib/Analysis/RegionStore.cpp index fbaa302d31..5f1c39c2b6 100644 --- a/lib/Analysis/RegionStore.cpp +++ b/lib/Analysis/RegionStore.cpp @@ -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); diff --git a/test/Analysis/ptr-arith.c b/test/Analysis/ptr-arith.c index 11c8708dcf..87c3eb8dfe 100644 --- a/test/Analysis/ptr-arith.c +++ b/test/Analysis/ptr-arith.c @@ -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];