Add -Wc99-compat warning for C11 unicode string and character literals.
authorRichard Smith <richard-llvm@metafoo.co.uk>
Mon, 11 Mar 2013 18:01:42 +0000 (18:01 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Mon, 11 Mar 2013 18:01:42 +0000 (18:01 +0000)
llvm-svn: 176817

clang/include/clang/Basic/DiagnosticLexKinds.td
clang/lib/Lex/Lexer.cpp
clang/test/Lexer/unicode-strings.c [new file with mode: 0644]

index f693257..7f66a87 100644 (file)
@@ -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;
index e6cc8b9..ed4666a 100644 (file)
@@ -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/clang/test/Lexer/unicode-strings.c b/clang/test/Lexer/unicode-strings.c
new file mode 100644 (file)
index 0000000..3ed1f76
--- /dev/null
@@ -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}}