summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/include/clang/Lex/LiteralSupport.h4
-rw-r--r--clang/lib/Lex/LiteralSupport.cpp31
2 files changed, 20 insertions, 15 deletions
diff --git a/clang/include/clang/Lex/LiteralSupport.h b/clang/include/clang/Lex/LiteralSupport.h
index 13da783312f..d4fd43bbd2f 100644
--- a/clang/include/clang/Lex/LiteralSupport.h
+++ b/clang/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/clang/lib/Lex/LiteralSupport.cpp b/clang/lib/Lex/LiteralSupport.cpp
index a52d951e754..a3184e90ad8 100644
--- a/clang/lib/Lex/LiteralSupport.cpp
+++ b/clang/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
OpenPOWER on IntegriCloud