]> granicus.if.org Git - clang/commitdiff
Warn about and truncate UCNs that are too big for their character literal type.
authorCraig Topper <craig.topper@gmail.com>
Fri, 19 Aug 2011 03:20:12 +0000 (03:20 +0000)
committerCraig Topper <craig.topper@gmail.com>
Fri, 19 Aug 2011 03:20:12 +0000 (03:20 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@138031 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Lex/LiteralSupport.cpp
test/Lexer/constants.c

index 20479199c4344b4cf2a1be5b0fa9a3ab1767c241..b82dbd863bfba8cd1d1968bfee9286cecc1ca205 100644 (file)
@@ -786,6 +786,7 @@ CharLiteralParser::CharLiteralParser(const char *begin, const char *end,
     if (begin[0] != '\\')     // If this is a normal character, consume it.
       ResultChar = *begin++;
     else {                    // Otherwise, this is an escape character.
+      unsigned CharWidth = getCharWidth(Kind, PP.getTargetInfo());
       // Check for UCN.
       if (begin[1] == 'u' || begin[1] == 'U') {
         uint32_t utf32 = 0;
@@ -796,9 +797,12 @@ CharLiteralParser::CharLiteralParser(const char *begin, const char *end,
           HadError = 1;
         }
         ResultChar = utf32;
+        if (CharWidth != 32 && (ResultChar >> CharWidth) != 0) {
+          PP.Diag(Loc, diag::warn_ucn_escape_too_large);
+          ResultChar &= ~0U >> (32-CharWidth);
+        }
       } else {
         // Otherwise, this is a non-UCN escape character.  Process it.
-        unsigned CharWidth = getCharWidth(Kind, PP.getTargetInfo());
         ResultChar = ProcessCharEscape(begin, end, HadError,
                                        FullSourceLoc(Loc,PP.getSourceManager()),
                                        CharWidth, &PP.getDiagnostics());
@@ -843,10 +847,6 @@ CharLiteralParser::CharLiteralParser(const char *begin, const char *end,
   // Transfer the value from APInt to uint64_t
   Value = LitVal.getZExtValue();
 
-  if (((isWide() && PP.getLangOptions().ShortWChar) || isUTF16()) &&
-      Value > 0xFFFF)
-    PP.Diag(Loc, diag::warn_ucn_escape_too_large);
-
   // 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
   // character constants are not sign extended in the this implementation:
index 3d2da2c764e6d536a6b1123099ae3784fc25a633..013103b1f5dd94b63515d5eab14c9a98560fae23 100644 (file)
@@ -65,3 +65,5 @@ double t1[] = {
 
 // PR7888
 double g = 1e100000000; // expected-warning {{too large}}
+
+char h = '\u1234'; // expected-warning {{character unicode escape sequence too long for its type}}