[cfe-commits] r142034 - in /cfe/trunk: include/clang/Basic/DiagnosticCommonKinds.td include/clang/Basic/DiagnosticGroups.td include/clang/Basic/DiagnosticLexKinds.td lib/Lex/Lexer.cpp lib/Lex/PPDirectives.cpp lib/Lex/PPExpressions.cpp lib/Lex/PPMacroExpansion.cpp test/SemaCXX/cxx98-compat-pedantic.cpp test/SemaCXX/cxx98-compat.cpp

Richard Smith richard-llvm at metafoo.co.uk
Fri Oct 14 18:18:56 PDT 2011


Author: rsmith
Date: Fri Oct 14 20:18:56 2011
New Revision: 142034

URL: http://llvm.org/viewvc/llvm-project?rev=142034&view=rev
Log:
-Wc++98-compat warnings for the lexer.

This also adds a -Wc++98-compat-pedantic for warning on constructs which would
be diagnosed by -std=c++98 -pedantic (that is, it warns even on C++11 features
which we enable by default, with no warning, in C++98 mode).

Added:
    cfe/trunk/test/SemaCXX/cxx98-compat-pedantic.cpp
Modified:
    cfe/trunk/include/clang/Basic/DiagnosticCommonKinds.td
    cfe/trunk/include/clang/Basic/DiagnosticGroups.td
    cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td
    cfe/trunk/lib/Lex/Lexer.cpp
    cfe/trunk/lib/Lex/PPDirectives.cpp
    cfe/trunk/lib/Lex/PPExpressions.cpp
    cfe/trunk/lib/Lex/PPMacroExpansion.cpp
    cfe/trunk/test/SemaCXX/cxx98-compat.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticCommonKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticCommonKinds.td?rev=142034&r1=142033&r2=142034&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticCommonKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticCommonKinds.td Fri Oct 14 20:18:56 2011
@@ -74,6 +74,9 @@
 def ext_longlong : Extension<
   "'long long' is an extension when C99 mode is not enabled">,
   InGroup<LongLong>;
+def warn_cxx98_compat_longlong : Warning<
+  "'long long' is incompatible with C++98">,
+  InGroup<CXX98CompatPedantic>, DefaultIgnore;
 def warn_integer_too_large : Warning<
   "integer constant is too large for its type">;
 def warn_integer_too_large_for_signed : Warning<

Modified: cfe/trunk/include/clang/Basic/DiagnosticGroups.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticGroups.td?rev=142034&r1=142033&r2=142034&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticGroups.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticGroups.td Fri Oct 14 20:18:56 2011
@@ -55,6 +55,8 @@
 def FormatZeroLength : DiagGroup<"format-zero-length">;
 
 def CXX98Compat : DiagGroup<"c++98-compat">;
+// Warnings for C++11 features which are Extensions in C++98 mode.
+def CXX98CompatPedantic : DiagGroup<"c++98-compat-pedantic", [CXX98Compat]>;
 
 def CXX11Narrowing : DiagGroup<"c++11-narrowing">;
 def : DiagGroup<"c++0x-narrowing", [CXX11Narrowing]>;

Modified: cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td?rev=142034&r1=142033&r2=142034&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td Fri Oct 14 20:18:56 2011
@@ -24,6 +24,11 @@
 def backslash_newline_space : Warning<
   "backslash and newline separated by space">;
 
+// Digraphs.
+def warn_cxx98_compat_less_colon_colon : Warning<
+  "'<::' is treated as digraph '<:' (aka '[') followed by ':' in C++98">,
+  InGroup<CXX98Compat>, DefaultIgnore;
+
 // Trigraphs.
 def trigraph_ignored : Warning<"trigraph ignored">, InGroup<Trigraphs>;
 def trigraph_ignored_block_comment : Warning<
@@ -67,6 +72,9 @@
   "; use PREFIX( )PREFIX to delimit raw string">;
 def err_unterminated_raw_string : Error<
   "raw string missing terminating delimiter )%0\"">;
+def warn_cxx98_compat_raw_string_literal : Warning<
+  "raw string literals are incompatible with C++98">,
+  InGroup<CXX98Compat>, DefaultIgnore;
 
 def ext_multichar_character_literal : ExtWarn<
   "multi-character character constant">, InGroup<MultiChar>;
@@ -112,6 +120,9 @@
   "character unicode escape sequence too long for its type">;
 def warn_ucn_not_valid_in_c89 : ExtWarn<
   "unicode escape sequences are only valid in C99 or C++">;
+def warn_cxx98_compat_unicode_literal : Warning<
+  "unicode literals are incompatible with C++98">,
+  InGroup<CXX98Compat>, DefaultIgnore;
 def err_unsupported_string_concat : Error<
   "unsupported non-standard concatenation of string literals">;
   
@@ -179,6 +190,9 @@
 def ext_pp_macro_redef : ExtWarn<"%0 macro redefined">;
 def ext_variadic_macro : Extension<"variadic macros were introduced in C99">,
   InGroup<VariadicMacros>;
+def warn_cxx98_compat_variadic_macro : Warning<
+  "variadic macros are incompatible with C++98">,
+  InGroup<CXX98CompatPedantic>, DefaultIgnore;
 def ext_named_variadic_macro : Extension<
   "named variadic macros are a GNU extension">, InGroup<VariadicMacros>;
 def ext_embedded_directive : Extension<
@@ -187,6 +201,9 @@
   "varargs argument missing, but tolerated as an extension">;
 def ext_empty_fnmacro_arg : Extension<
   "empty macro arguments were standardized in C99">;
+def warn_cxx98_compat_empty_fnmacro_arg : Warning<
+  "empty macro argument list is incompatible with C++98">,
+  InGroup<CXX98CompatPedantic>, DefaultIgnore;
 
 def err_pp_invalid_directive : Error<"invalid preprocessing directive">;
 def err_pp_hash_error : Error<"#error%0">;
@@ -334,6 +351,9 @@
   "invalid line marker flag '2': cannot pop empty include stack">;
 def ext_pp_line_too_big : Extension<
   "C requires #line number to be less than %0, allowed as extension">;
+def warn_cxx98_compat_pp_line_too_big : Warning<
+  "#line number greater than 32767 is incompatible with C++98">,
+  InGroup<CXX98CompatPedantic>, DefaultIgnore;
 
 def err_pp_export_non_macro : Error<"no macro named %0 to export">;
 

Modified: cfe/trunk/lib/Lex/Lexer.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/Lexer.cpp?rev=142034&r1=142033&r2=142034&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/Lexer.cpp (original)
+++ cfe/trunk/lib/Lex/Lexer.cpp Fri Oct 14 20:18:56 2011
@@ -1373,6 +1373,12 @@
                              tok::TokenKind Kind) {
   const char *NulCharacter = 0; // Does this string contain the \0 character?
 
+  if (!isLexingRawMode() &&
+      (Kind == tok::utf8_string_literal ||
+       Kind == tok::utf16_string_literal ||
+       Kind == tok::utf32_string_literal))
+    Diag(BufferPtr, diag::warn_cxx98_compat_unicode_literal);
+
   char C = getAndAdvanceChar(CurPtr, Result);
   while (C != '"') {
     // Skip escaped characters.  Escaped newlines will already be processed by
@@ -1419,6 +1425,9 @@
   //  any transformations performed in phases 1 and 2 (trigraphs,
   //  universal-character-names, and line splicing) are reverted.
 
+  if (!isLexingRawMode())
+    Diag(BufferPtr, diag::warn_cxx98_compat_raw_string_literal);
+
   unsigned PrefixLen = 0;
 
   while (PrefixLen != 16 && isRawStringDelimBody(CurPtr[PrefixLen]))
@@ -1523,6 +1532,10 @@
                             tok::TokenKind Kind) {
   const char *NulCharacter = 0; // Does this character contain the \0 character?
 
+  if (!isLexingRawMode() &&
+      (Kind == tok::utf16_char_constant || Kind == tok::utf32_char_constant))
+    Diag(BufferPtr, diag::warn_cxx98_compat_unicode_literal);
+
   char C = getAndAdvanceChar(CurPtr, Result);
   if (C == '\'') {
     if (!isLexingRawMode() && !Features.AsmPreprocessor)
@@ -2799,6 +2812,8 @@
         char After = getCharAndSize(CurPtr + SizeTmp + SizeTmp2, SizeTmp3);
         if (After != ':' && After != '>') {
           Kind = tok::less;
+          if (!isLexingRawMode())
+            Diag(BufferPtr, diag::warn_cxx98_compat_less_colon_colon);
           break;
         }
       }

Modified: cfe/trunk/lib/Lex/PPDirectives.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PPDirectives.cpp?rev=142034&r1=142033&r2=142034&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/PPDirectives.cpp (original)
+++ cfe/trunk/lib/Lex/PPDirectives.cpp Fri Oct 14 20:18:56 2011
@@ -777,6 +777,8 @@
     LineLimit = 2147483648U;
   if (LineNo >= LineLimit)
     Diag(DigitTok, diag::ext_pp_line_too_big) << LineLimit;
+  else if (Features.CPlusPlus0x && LineNo >= 32768U)
+    Diag(DigitTok, diag::warn_cxx98_compat_pp_line_too_big);
 
   int FilenameID = -1;
   Token StrTok;
@@ -1367,8 +1369,10 @@
       Diag(Tok, diag::err_pp_expected_ident_in_arg_list);
       return true;
     case tok::ellipsis:  // #define X(... -> C99 varargs
-      if (!Features.C99 && !Features.CPlusPlus0x)
-        Diag(Tok, diag::ext_variadic_macro);
+      if (!Features.C99)
+        Diag(Tok, Features.CPlusPlus0x ? 
+             diag::warn_cxx98_compat_variadic_macro :
+             diag::ext_variadic_macro);
 
       // Lex the token after the identifier.
       LexUnexpandedToken(Tok);

Modified: cfe/trunk/lib/Lex/PPExpressions.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PPExpressions.cpp?rev=142034&r1=142033&r2=142034&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/PPExpressions.cpp (original)
+++ cfe/trunk/lib/Lex/PPExpressions.cpp Fri Oct 14 20:18:56 2011
@@ -216,9 +216,9 @@
     assert(Literal.isIntegerLiteral() && "Unknown ppnumber");
 
     // long long is a C99 feature.
-    if (!PP.getLangOptions().C99 && !PP.getLangOptions().CPlusPlus0x
-        && Literal.isLongLong)
-      PP.Diag(PeekTok, diag::ext_longlong);
+    if (!PP.getLangOptions().C99 && Literal.isLongLong)
+      PP.Diag(PeekTok, PP.getLangOptions().CPlusPlus0x ?
+              diag::warn_cxx98_compat_longlong : diag::ext_longlong);
 
     // Parse the integer literal into Result.
     if (Literal.GetIntegerValue(Result.Val)) {
@@ -778,4 +778,3 @@
   DisableMacroExpansion = DisableMacroExpansionAtStartOfDirective;
   return ResVal.Val != 0;
 }
-

Modified: cfe/trunk/lib/Lex/PPMacroExpansion.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PPMacroExpansion.cpp?rev=142034&r1=142033&r2=142034&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/PPMacroExpansion.cpp (original)
+++ cfe/trunk/lib/Lex/PPMacroExpansion.cpp Fri Oct 14 20:18:56 2011
@@ -421,8 +421,10 @@
 
     // Empty arguments are standard in C99 and C++0x, and are supported as an extension in
     // other modes.
-    if (ArgTokens.size() == ArgTokenStart && !Features.C99 && !Features.CPlusPlus0x)
-      Diag(Tok, diag::ext_empty_fnmacro_arg);
+    if (ArgTokens.size() == ArgTokenStart && !Features.C99)
+      Diag(Tok, Features.CPlusPlus0x ?
+           diag::warn_cxx98_compat_empty_fnmacro_arg :
+           diag::ext_empty_fnmacro_arg);
 
     // Add a marker EOF token to the end of the token list for this argument.
     Token EOFTok;

Added: cfe/trunk/test/SemaCXX/cxx98-compat-pedantic.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx98-compat-pedantic.cpp?rev=142034&view=auto
==============================================================================
--- cfe/trunk/test/SemaCXX/cxx98-compat-pedantic.cpp (added)
+++ cfe/trunk/test/SemaCXX/cxx98-compat-pedantic.cpp Fri Oct 14 20:18:56 2011
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++11 -Wc++98-compat-pedantic -verify %s
+// RUN: %clang_cc1 -fsyntax-only -std=c++98 -Werror %s
+
+// -Wc++98-compat-pedantic warns on C++11 features which we accept without a
+// warning in C++98 mode.
+
+#line 32767 // ok
+#line 32768 // expected-warning {{#line number greater than 32767 is incompatible with C++98}}
+
+#define VA_MACRO(x, ...) x // expected-warning {{variadic macros are incompatible with C++98}}
+VA_MACRO(,x) // expected-warning {{empty macro argument list is incompatible with C++98}}

Modified: cfe/trunk/test/SemaCXX/cxx98-compat.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx98-compat.cpp?rev=142034&r1=142033&r2=142034&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/cxx98-compat.cpp (original)
+++ cfe/trunk/test/SemaCXX/cxx98-compat.cpp Fri Oct 14 20:18:56 2011
@@ -11,3 +11,20 @@
 
 int alignas(8) with_alignas; // expected-warning {{'alignas' is incompatible with C++98}}
 int with_attribute [[ ]]; // expected-warning {{attributes are incompatible with C++98}}
+
+void Literals() {
+  (void)u8"str"; // expected-warning {{unicode literals are incompatible with C++98}}
+  (void)u"str"; // expected-warning {{unicode literals are incompatible with C++98}}
+  (void)U"str"; // expected-warning {{unicode literals are incompatible with C++98}}
+  (void)u'x'; // expected-warning {{unicode literals are incompatible with C++98}}
+  (void)U'x'; // expected-warning {{unicode literals are incompatible with C++98}}
+
+  (void)u8R"X(str)X"; // expected-warning {{raw string literals are incompatible with C++98}}
+  (void)uR"X(str)X"; // expected-warning {{raw string literals are incompatible with C++98}}
+  (void)UR"X(str)X"; // expected-warning {{raw string literals are incompatible with C++98}}
+  (void)R"X(str)X"; // expected-warning {{raw string literals are incompatible with C++98}}
+  (void)LR"X(str)X"; // expected-warning {{raw string literals are incompatible with C++98}}
+}
+
+template<typename T> struct S {};
+S<::S<void> > s; // expected-warning {{'<::' is treated as digraph '<:' (aka '[') followed by ':' in C++98}}





More information about the cfe-commits mailing list