diff --git a/lib/Lex/LiteralSupport.cpp b/lib/Lex/LiteralSupport.cpp index 20479199c4..b82dbd863b 100644 --- a/lib/Lex/LiteralSupport.cpp +++ b/lib/Lex/LiteralSupport.cpp @@ -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: diff --git a/test/Lexer/constants.c b/test/Lexer/constants.c index 3d2da2c764..013103b1f5 100644 --- a/test/Lexer/constants.c +++ b/test/Lexer/constants.c @@ -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}}