]> granicus.if.org Git - clang/commitdiff
Use an APInt of target int size to detect overflow while parsing multichars.
authorSanjiv Gupta <sanjiv.gupta@microchip.com>
Tue, 21 Apr 2009 02:21:29 +0000 (02:21 +0000)
committerSanjiv Gupta <sanjiv.gupta@microchip.com>
Tue, 21 Apr 2009 02:21:29 +0000 (02:21 +0000)
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

include/clang/Lex/LiteralSupport.h
lib/Lex/LiteralSupport.cpp

index 13da783312fd08a5fd036d43c9debcdde2aa5b5c..d4fd43bbd2f04e23aa68dde82398b54b8b834a5b 100644 (file)
@@ -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
index a52d951e7543f1d62c76120398ccfeb51c56091f..a3184e90ad8d1185f81f6a933c14a73ce94b23d4 100644 (file)
@@ -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