[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