aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSanjiv Gupta <sanjiv.gupta@microchip.com>2009-04-21 02:21:29 +0000
committerSanjiv Gupta <sanjiv.gupta@microchip.com>2009-04-21 02:21:29 +0000
commit4bc11af9bed1d4a247e3db1fcb754d410ad99099 (patch)
treedb1e5354af2f630cfb57d2ac37fbc694cff19c22
parent86fa7502706b993ebbe5b5be147604c3bed0fcad (diff)
Use an APInt of target int size to detect overflow while parsing multichars.
So 'abc' on i16 platforms will warn but not on i32 platforms. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@69653 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/Lex/LiteralSupport.h4
-rw-r--r--lib/Lex/LiteralSupport.cpp31
2 files changed, 20 insertions, 15 deletions
diff --git a/include/clang/Lex/LiteralSupport.h b/include/clang/Lex/LiteralSupport.h
index 13da783312..d4fd43bbd2 100644
--- a/include/clang/Lex/LiteralSupport.h
+++ b/include/clang/Lex/LiteralSupport.h
@@ -124,7 +124,7 @@ private:
/// CharLiteralParser - Perform interpretation and semantic analysis of a
/// character literal.
class CharLiteralParser {
- unsigned Value;
+ uint64_t Value;
bool IsWide;
bool HadError;
public:
@@ -133,7 +133,7 @@ public:
bool hadError() const { return HadError; }
bool isWide() const { return IsWide; }
- unsigned getValue() const { return Value; }
+ uint64_t getValue() const { return Value; }
};
/// StringLiteralParser - This decodes string escape characters and performs
diff --git a/lib/Lex/LiteralSupport.cpp b/lib/Lex/LiteralSupport.cpp
index a52d951e75..a3184e90ad 100644
--- a/lib/Lex/LiteralSupport.cpp
+++ b/lib/Lex/LiteralSupport.cpp
@@ -622,7 +622,6 @@ CharLiteralParser::CharLiteralParser(const char *begin, const char *end,
SourceLocation Loc, Preprocessor &PP) {
// At this point we know that the character matches the regex "L?'.*'".
HadError = false;
- Value = 0;
// Determine if this is a wide character.
IsWide = begin[0] == 'L';
@@ -632,21 +631,23 @@ CharLiteralParser::CharLiteralParser(const char *begin, const char *end,
assert(begin[0] == '\'' && "Invalid token lexed");
++begin;
- // FIXME: This assumes that 'int' is 32-bits in overflow calculation, and the
- // size of "value".
- assert(PP.getTargetInfo().getIntWidth() == 32 &&
- "Assumes sizeof(int) == 4 for now");
- // FIXME: This assumes that wchar_t is 32-bits for now.
- assert(PP.getTargetInfo().getWCharWidth() == 32 &&
- "Assumes sizeof(wchar_t) == 4 for now");
+ // FIXME: The "Value" is an uint64_t so we can handle char literals of
+ // upto 64-bits.
+ assert(PP.getTargetInfo().getIntWidth() <= 64 &&
+ "Assumes sizeof(int) on target is <= 64");
+ assert(PP.getTargetInfo().getWCharWidth() <= 64 &&
+ "Assumes sizeof(wchar) on target is <= 64");
// FIXME: This extensively assumes that 'char' is 8-bits.
assert(PP.getTargetInfo().getCharWidth() == 8 &&
"Assumes char is 8 bits");
+
+ // This is what we will use for overflow detection
+ llvm::APInt LitVal(PP.getTargetInfo().getIntWidth(), 0);
bool isFirstChar = true;
bool isMultiChar = false;
while (begin[0] != '\'') {
- unsigned ResultChar;
+ uint64_t ResultChar;
if (begin[0] != '\\') // If this is a normal character, consume it.
ResultChar = *begin++;
else // Otherwise, this is an escape character.
@@ -667,19 +668,23 @@ CharLiteralParser::CharLiteralParser(const char *begin, const char *end,
if (IsWide) {
// Emulate GCC's (unintentional?) behavior: L'ab' -> L'b'.
- Value = 0;
+ LitVal = 0;
} else {
// Narrow character literals act as though their value is concatenated
// in this implementation.
- if (((Value << 8) >> 8) != Value)
+ if ((LitVal.shl(8)).lshr(8) != LitVal)
+ // if (((LitVal << 8) >> 8) != LitVal)
PP.Diag(Loc, diag::warn_char_constant_too_large);
- Value <<= 8;
+ LitVal <<= 8;
}
}
- Value += ResultChar;
+ LitVal = LitVal + ResultChar;
isFirstChar = false;
}
+
+ // Transfer the value from APInt to uint64_t
+ Value = LitVal.getZExtValue();
// If this is a single narrow character, sign extend it (e.g. '\xFF' is "-1")
// if 'char' is signed for this target (C99 6.4.4.4p10). Note that multiple