aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCraig Topper <craig.topper@gmail.com>2011-08-19 03:20:12 +0000
committerCraig Topper <craig.topper@gmail.com>2011-08-19 03:20:12 +0000
commit0473cd52eac6f1e831777ed899be3ea4509c7b24 (patch)
treef9116d4a51184ac8d88a673b7feffaead0da1b29
parentfac4ece118d43e43e625c6d2b9a98905b1372d51 (diff)
Warn about and truncate UCNs that are too big for their character literal type.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@138031 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Lex/LiteralSupport.cpp10
-rw-r--r--test/Lexer/constants.c2
2 files changed, 7 insertions, 5 deletions
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}}