[cfe-commits] r39382 - in /cfe/cfe/trunk: Lex/LiteralSupport.cpp include/clang/Lex/LiteralSupport.h

clattner at cs.uiuc.edu clattner at cs.uiuc.edu
Wed Jul 11 09:43:49 PDT 2007


Author: clattner
Date: Wed Jul 11 11:43:48 2007
New Revision: 39382

URL: http://llvm.org/viewvc/llvm-project?rev=39382&view=rev
Log:
Minor enhancements to GetIntegerValue(APInt):
  * Detect overflow correctly.  When it occurs, return the truncated value.
  * Add fixme for radix analysis.

Modified:
    cfe/cfe/trunk/Lex/LiteralSupport.cpp
    cfe/cfe/trunk/include/clang/Lex/LiteralSupport.h

Modified: cfe/cfe/trunk/Lex/LiteralSupport.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Lex/LiteralSupport.cpp?rev=39382&r1=39381&r2=39382&view=diff

==============================================================================
--- cfe/cfe/trunk/Lex/LiteralSupport.cpp (original)
+++ cfe/cfe/trunk/Lex/LiteralSupport.cpp Wed Jul 11 11:43:48 2007
@@ -266,32 +266,45 @@
 }
 
 /// GetIntegerValue - Convert this numeric literal value to an APInt that
-/// matches Val's input width.  If there is an overflow, saturate Val to zero
-/// and return false.  Otherwise, set Val and return true.
+/// matches Val's input width.  If there is an overflow, set Val to the low bits
+/// of the result and return true.  Otherwise, return false.
 bool NumericLiteralParser::GetIntegerValue(APInt &Val) {
   Val = 0;
   s = DigitsBegin;
 
-  // FIXME: This doesn't handle sign right, doesn't autopromote to wider
-  // integer, and is generally not conformant.
   APInt RadixVal(Val.getBitWidth(), radix);
   APInt CharVal(Val.getBitWidth(), 0);
   APInt OldVal = Val;
+  
+  bool OverflowOccurred = false;
   while (s < SuffixBegin) {
     unsigned C = HexLetterToVal(*s++);
     
     // If this letter is out of bound for this radix, reject it.
-    if (C >= radix) { Val = 0; return false; }
+    if (C >= radix) {
+      // FIXME: This is an error, not a warning.  This should be caught by
+      // NumericLiteralParser ctor.
+      C = C % radix;
+      OverflowOccurred = true;
+    }
     
     CharVal = C;
     
+    // Add the digit to the value in the appropriate radix.  If adding in digits
+    // made the value smaller, then this overflowed.
     OldVal = Val;
+
+    // Multiply by radix, did overflow occur on the multiply?
     Val *= RadixVal;
+    OverflowOccurred |= Val.udiv(RadixVal) != OldVal;
+
+    OldVal = Val;
+    // Add value, did overflow occur on the value?
     Val += CharVal;
-    if (OldVal.ugt(Val))
-      return false; // Overflow!
+    OverflowOccurred |= Val.ult(OldVal);
+    OverflowOccurred |= Val.ult(CharVal);
   }
-  return true;
+  return OverflowOccurred;
 }
 
 

Modified: cfe/cfe/trunk/include/clang/Lex/LiteralSupport.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/Lex/LiteralSupport.h?rev=39382&r1=39381&r2=39382&view=diff

==============================================================================
--- cfe/cfe/trunk/include/clang/Lex/LiteralSupport.h (original)
+++ cfe/cfe/trunk/include/clang/Lex/LiteralSupport.h Wed Jul 11 11:43:48 2007
@@ -63,9 +63,15 @@
   /// type (int, unsigned, long, unsigned long, long long, unsigned long long) 
   /// will be done elsewhere - the size computation is target dependent. We  
   /// return true if the value fit into "val", false otherwise. 
+  /// NOTE: The api of these returns an inverted value for 'overflow' than the
+  /// version below does.
   bool GetIntegerValue(uintmax_t &val);
   bool GetIntegerValue(int &val);
-  bool GetIntegerValue(APInt &Val);  //< Return the same width as Val.
+  
+  /// GetIntegerValue - Convert this numeric literal value to an APInt that
+  /// matches Val's input width.  If there is an overflow, set Val to the low
+  /// bits of the result and return true.  Otherwise, return false.
+  bool GetIntegerValue(APInt &Val);
 
 private:  
   void Diag(SourceLocation Loc, unsigned DiagID, 





More information about the cfe-commits mailing list