]> granicus.if.org Git - clang/commitdiff
Fix failure reported by Sebastian of test/Analysis/ptr-arith.c when the target
authorTed Kremenek <kremenek@apple.com>
Fri, 13 Mar 2009 15:35:24 +0000 (15:35 +0000)
committerTed Kremenek <kremenek@apple.com>
Fri, 13 Mar 2009 15:35:24 +0000 (15:35 +0000)
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

include/clang/Analysis/PathSensitive/BasicValueFactory.h
lib/Analysis/RegionStore.cpp
test/Analysis/ptr-arith.c

index 18ae1d88e4ec06892f4f517a22fc8e83b0d4b457..c0a28c3fd1d71b7c3d3fa0127a28cf9f94a46184 100644 (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) {
index fbaa302d31f92387f3bc0565e4302312ee369883..5f1c39c2b6927cd397d9b2e7b9c7bbc6e39e88d7 100644 (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);
index 11c8708dcf29ffe6d5bb839aed228564671d7c3e..87c3eb8dfef68d4f69ae2bf2e5f2a03d45bcadf0 100644 (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];