diff --git a/include/clang/Basic/DiagnosticLexKinds.td b/include/clang/Basic/DiagnosticLexKinds.td index f693257ec9c3bfc91e067a5bf8980e3f9bc5389e..7f66a87d612c5ec36dc291dcfa770c35bb0595ee 100644 --- a/include/clang/Basic/DiagnosticLexKinds.td +++ b/include/clang/Basic/DiagnosticLexKinds.td @@ -182,6 +182,9 @@ def ext_string_too_long : Extension<"string literal of length %0 exceeds " "support">, InGroup<OverlengthStrings>; def err_character_too_large : Error< "character too large for enclosing character literal type">; +def warn_c99_compat_unicode_literal : Warning< + "unicode literals are incompatible with C99">, + InGroup<C99Compat>, DefaultIgnore; def warn_cxx98_compat_unicode_literal : Warning< "unicode literals are incompatible with C++98">, InGroup<CXX98Compat>, DefaultIgnore; diff --git a/lib/Lex/Lexer.cpp b/lib/Lex/Lexer.cpp index e6cc8b929c28763a2011b9901d47ac75e5bbb11b..ed4666aa2117ff08b71182eb24ee5de403207a0c 100644 --- a/lib/Lex/Lexer.cpp +++ b/lib/Lex/Lexer.cpp @@ -1629,9 +1629,10 @@ void Lexer::LexStringLiteral(Token &Result, const char *CurPtr, if (!isLexingRawMode() && (Kind == tok::utf8_string_literal || Kind == tok::utf16_string_literal || - Kind == tok::utf32_string_literal) && - getLangOpts().CPlusPlus) - Diag(BufferPtr, diag::warn_cxx98_compat_unicode_literal); + Kind == tok::utf32_string_literal)) + Diag(BufferPtr, getLangOpts().CPlusPlus + ? diag::warn_cxx98_compat_unicode_literal + : diag::warn_c99_compat_unicode_literal); char C = getAndAdvanceChar(CurPtr, Result); while (C != '"') { @@ -1795,9 +1796,10 @@ void Lexer::LexCharConstant(Token &Result, const char *CurPtr, const char *NulCharacter = 0; // Does this character contain the \0 character? if (!isLexingRawMode() && - (Kind == tok::utf16_char_constant || Kind == tok::utf32_char_constant) && - getLangOpts().CPlusPlus) - Diag(BufferPtr, diag::warn_cxx98_compat_unicode_literal); + (Kind == tok::utf16_char_constant || Kind == tok::utf32_char_constant)) + Diag(BufferPtr, getLangOpts().CPlusPlus + ? diag::warn_cxx98_compat_unicode_literal + : diag::warn_c99_compat_unicode_literal); char C = getAndAdvanceChar(CurPtr, Result); if (C == '\'') { diff --git a/test/Lexer/unicode-strings.c b/test/Lexer/unicode-strings.c new file mode 100644 index 0000000000000000000000000000000000000000..3ed1f7682993415013e157d07ad99d0b93f6fabe --- /dev/null +++ b/test/Lexer/unicode-strings.c @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 -x c -std=c11 -Werror %s +// RUN: %clang_cc1 -x c++ -std=c++11 -Werror %s +// RUN: %clang_cc1 -x c -std=c11 -Wc99-compat -verify %s +// RUN: %clang_cc1 -x c++ -std=c++11 -Wc++98-compat -verify %s + +#ifndef __cplusplus +typedef __CHAR16_TYPE__ char16_t; +typedef __CHAR32_TYPE__ char32_t; +#else +// expected-warning@17 {{'char16_t' type specifier is incompatible with C++98}} +// expected-warning@18 {{'char32_t' type specifier is incompatible with C++98}} +// expected-warning@20 {{'char16_t' type specifier is incompatible with C++98}} +// expected-warning@21 {{'char32_t' type specifier is incompatible with C++98}} +#endif + +const char *a = u8"abcd"; // expected-warning {{unicode literals are incompatible with}} +const char16_t *b = u"abcd"; // expected-warning {{unicode literals are incompatible with}} +const char32_t *c = U"abcd"; // expected-warning {{unicode literals are incompatible with}} + +char16_t d = u'a'; // expected-warning {{unicode literals are incompatible with}} +char32_t e = U'a'; // expected-warning {{unicode literals are incompatible with}}