[cfe-commits] r160618 - in /cfe/trunk: include/clang/Basic/DiagnosticGroups.td include/clang/Basic/DiagnosticParseKinds.td include/clang/Parse/Parser.h lib/Parse/ParseDecl.cpp lib/Parse/ParseDeclCXX.cpp lib/Parse/Parser.cpp test/Misc/warning-flags.c test/Parser/cxx-class.cpp test/Parser/cxx-decl.cpp test/Parser/cxx-extra-semi.cpp test/Parser/cxx0x-decl.cpp

Richard Smith richard-llvm at metafoo.co.uk
Sun Jul 22 22:45:25 PDT 2012


Author: rsmith
Date: Mon Jul 23 00:45:25 2012
New Revision: 160618

URL: http://llvm.org/viewvc/llvm-project?rev=160618&view=rev
Log:
Add diagnostics for comma at end of enum and for extra semicolon at namespace
scope to -Wc++11-extensions. Move extra semicolon after member function
definition diagnostic out of -pedantic, since C++ allows a single semicolon
there. Keep it in -Wextra-semi, though, since it's still questionable.

Modified:
    cfe/trunk/include/clang/Basic/DiagnosticGroups.td
    cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td
    cfe/trunk/include/clang/Parse/Parser.h
    cfe/trunk/lib/Parse/ParseDecl.cpp
    cfe/trunk/lib/Parse/ParseDeclCXX.cpp
    cfe/trunk/lib/Parse/Parser.cpp
    cfe/trunk/test/Misc/warning-flags.c
    cfe/trunk/test/Parser/cxx-class.cpp
    cfe/trunk/test/Parser/cxx-decl.cpp
    cfe/trunk/test/Parser/cxx-extra-semi.cpp
    cfe/trunk/test/Parser/cxx0x-decl.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticGroups.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticGroups.td?rev=160618&r1=160617&r2=160618&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticGroups.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticGroups.td Mon Jul 23 00:45:25 2012
@@ -62,6 +62,8 @@
 def Documentation : DiagGroup<"documentation", [DocumentationHTML]>;
 def EmptyBody : DiagGroup<"empty-body">;
 def ExtraTokens : DiagGroup<"extra-tokens">;
+def CXX11ExtraSemi : DiagGroup<"c++11-extra-semi">;
+def ExtraSemi : DiagGroup<"extra-semi", [CXX11ExtraSemi]>;
 
 def FormatExtraArgs : DiagGroup<"format-extra-args">;
 def FormatZeroLength : DiagGroup<"format-zero-length">;
@@ -404,7 +406,7 @@
 
 // A warning group for warnings about using C++11 features as extensions in
 // earlier C++ versions.
-def CXX11 : DiagGroup<"c++11-extensions">;
+def CXX11 : DiagGroup<"c++11-extensions", [CXX11ExtraSemi]>;
 def : DiagGroup<"c++0x-extensions", [CXX11]>;
 def DelegatingCtorCycles :
   DiagGroup<"delegating-ctor-cycles">;

Modified: cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td?rev=160618&r1=160617&r2=160618&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td Mon Jul 23 00:45:25 2012
@@ -31,8 +31,14 @@
   "outside of a function|"
   "inside a %1|"
   "inside instance variable list|"
-  "after function definition}0">,
-  InGroup<DiagGroup<"extra-semi">>;
+  "after member function definition}0">,
+  InGroup<ExtraSemi>;
+def ext_extra_semi_cxx11 : Extension<
+  "extra ';' outside of a function is a C++11 extension">,
+  InGroup<CXX11ExtraSemi>;
+def warn_extra_semi_after_mem_fn_def : Warning<
+  "extra ';' after member function definition">,
+  InGroup<ExtraSemi>, DefaultIgnore;
 
 def ext_duplicate_declspec : Extension<"duplicate '%0' declaration specifier">;
 def ext_plain_complex : ExtWarn<
@@ -61,9 +67,12 @@
   "compound literals are a C99-specific feature">, InGroup<C99>;
 def ext_c99_flexible_array_member : Extension<
   "Flexible array members are a C99-specific feature">, InGroup<C99>;
-def ext_enumerator_list_comma : Extension<
-  "commas at the end of enumerator lists are a %select{C99|C++11}0-specific "
-  "feature">;
+def ext_enumerator_list_comma_c : Extension<
+  "commas at the end of enumerator lists are a C99-specific "
+  "feature">, InGroup<C99>;
+def ext_enumerator_list_comma_cxx : Extension<
+  "commas at the end of enumerator lists are a C++11 extension">,
+  InGroup<CXX11>;
 def warn_cxx98_compat_enumerator_list_comma : Warning<
   "commas at the end of enumerator lists are incompatible with C++98">,
   InGroup<CXX98CompatPedantic>, DefaultIgnore;

Modified: cfe/trunk/include/clang/Parse/Parser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=160618&r1=160617&r2=160618&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Mon Jul 23 00:45:25 2012
@@ -596,16 +596,16 @@
   /// to the semicolon, consumes that extra token.
   bool ExpectAndConsumeSemi(unsigned DiagID);
 
-  /// \brief The kind of extra semi diagnostic to emit. 
+  /// \brief The kind of extra semi diagnostic to emit.
   enum ExtraSemiKind {
     OutsideFunction = 0,
     InsideStruct = 1,
     InstanceVariableList = 2,
-    AfterDefinition = 3
+    AfterMemberFunctionDefinition = 3
   };
 
   /// \brief Consume any extra semi-colons until the end of the line.
-  void ConsumeExtraSemi(ExtraSemiKind Kind, const char* DiagMsg = "");
+  void ConsumeExtraSemi(ExtraSemiKind Kind, unsigned TST = TST_unspecified);
 
   //===--------------------------------------------------------------------===//
   // Scope manipulation

Modified: cfe/trunk/lib/Parse/ParseDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=160618&r1=160617&r2=160618&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseDecl.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDecl.cpp Mon Jul 23 00:45:25 2012
@@ -2876,8 +2876,7 @@
 
     // Check for extraneous top-level semicolon.
     if (Tok.is(tok::semi)) {
-      ConsumeExtraSemi(InsideStruct,
-                       DeclSpec::getSpecifierName((DeclSpec::TST)TagType));
+      ConsumeExtraSemi(InsideStruct, TagType);
       continue;
     }
 
@@ -3373,8 +3372,9 @@
 
     if (Tok.isNot(tok::identifier)) {
       if (!getLangOpts().C99 && !getLangOpts().CPlusPlus0x)
-        Diag(CommaLoc, diag::ext_enumerator_list_comma)
-          << getLangOpts().CPlusPlus
+        Diag(CommaLoc, getLangOpts().CPlusPlus ?
+               diag::ext_enumerator_list_comma_cxx :
+               diag::ext_enumerator_list_comma_c)
           << FixItHint::CreateRemoval(CommaLoc);
       else if (getLangOpts().CPlusPlus0x)
         Diag(CommaLoc, diag::warn_cxx98_compat_enumerator_list_comma)

Modified: cfe/trunk/lib/Parse/ParseDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDeclCXX.cpp?rev=160618&r1=160617&r2=160618&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseDeclCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDeclCXX.cpp Mon Jul 23 00:45:25 2012
@@ -1984,7 +1984,7 @@
 
       // Consume the ';' - it's optional unless we have a delete or default
       if (Tok.is(tok::semi))
-        ConsumeExtraSemi(AfterDefinition);
+        ConsumeExtraSemi(AfterMemberFunctionDefinition);
 
       return;
     }
@@ -2334,8 +2334,7 @@
 
       // Check for extraneous top-level semicolon.
       if (Tok.is(tok::semi)) {
-        ConsumeExtraSemi(InsideStruct,
-                         DeclSpec::getSpecifierName((DeclSpec::TST)TagType));
+        ConsumeExtraSemi(InsideStruct, TagType);
         continue;
       }
 
@@ -3060,8 +3059,7 @@
 
     // Check for extraneous top-level semicolon.
     if (Tok.is(tok::semi)) {
-      ConsumeExtraSemi(InsideStruct,
-                       DeclSpec::getSpecifierName((DeclSpec::TST)TagType));
+      ConsumeExtraSemi(InsideStruct, TagType);
       continue;
     }
 

Modified: cfe/trunk/lib/Parse/Parser.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/Parser.cpp?rev=160618&r1=160617&r2=160618&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/Parser.cpp (original)
+++ cfe/trunk/lib/Parse/Parser.cpp Mon Jul 23 00:45:25 2012
@@ -220,31 +220,40 @@
   return ExpectAndConsume(tok::semi, DiagID);
 }
 
-void Parser::ConsumeExtraSemi(ExtraSemiKind Kind, const char* DiagMsg) {
+void Parser::ConsumeExtraSemi(ExtraSemiKind Kind, unsigned TST) {
   if (!Tok.is(tok::semi)) return;
 
-  // AfterDefinition should only warn when placed on the same line as the
-  // definition.  Otherwise, defer to another semi warning.
-  if (Kind == AfterDefinition && Tok.isAtStartOfLine()) return;
-
+  bool HadMultipleSemis = false;
   SourceLocation StartLoc = Tok.getLocation();
   SourceLocation EndLoc = Tok.getLocation();
   ConsumeToken();
 
   while ((Tok.is(tok::semi) && !Tok.isAtStartOfLine())) {
+    HadMultipleSemis = true;
     EndLoc = Tok.getLocation();
     ConsumeToken();
   }
 
-  if (Kind == OutsideFunction && getLangOpts().CPlusPlus0x) {
-    Diag(StartLoc, diag::warn_cxx98_compat_top_level_semi)
-        << FixItHint::CreateRemoval(SourceRange(StartLoc, EndLoc));
+  // C++11 allows extra semicolons at namespace scope, but not in any of the
+  // other contexts.
+  if (Kind == OutsideFunction && getLangOpts().CPlusPlus) {
+    if (getLangOpts().CPlusPlus0x)
+      Diag(StartLoc, diag::warn_cxx98_compat_top_level_semi)
+          << FixItHint::CreateRemoval(SourceRange(StartLoc, EndLoc));
+    else
+      Diag(StartLoc, diag::ext_extra_semi_cxx11)
+          << FixItHint::CreateRemoval(SourceRange(StartLoc, EndLoc));
     return;
   }
 
-  Diag(StartLoc, diag::ext_extra_semi)
-      << Kind << DiagMsg << FixItHint::CreateRemoval(SourceRange(StartLoc,
-                                                                 EndLoc));
+  if (Kind != AfterMemberFunctionDefinition || HadMultipleSemis)
+    Diag(StartLoc, diag::ext_extra_semi)
+        << Kind << DeclSpec::getSpecifierName((DeclSpec::TST)TST)
+        << FixItHint::CreateRemoval(SourceRange(StartLoc, EndLoc));
+  else
+    // A single semicolon is valid after a member function definition.
+    Diag(StartLoc, diag::warn_extra_semi_after_mem_fn_def)
+      << FixItHint::CreateRemoval(SourceRange(StartLoc, EndLoc));
 }
 
 //===----------------------------------------------------------------------===//

Modified: cfe/trunk/test/Misc/warning-flags.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Misc/warning-flags.c?rev=160618&r1=160617&r2=160618&view=diff
==============================================================================
--- cfe/trunk/test/Misc/warning-flags.c (original)
+++ cfe/trunk/test/Misc/warning-flags.c Mon Jul 23 00:45:25 2012
@@ -150,8 +150,6 @@
 CHECK-NEXT:   warn_weak_identifier_undeclared
 CHECK-NEXT:   warn_weak_import
 
-The list of warnings in -Wpedenatic should NEVER grow.
-
-CHECK: Number in -Wpedantic (not covered by other -W flags): 71
-
+The list of warnings in -Wpedantic should NEVER grow.
 
+CHECK: Number in -Wpedantic (not covered by other -W flags): 70

Modified: cfe/trunk/test/Parser/cxx-class.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/cxx-class.cpp?rev=160618&r1=160617&r2=160618&view=diff
==============================================================================
--- cfe/trunk/test/Parser/cxx-class.cpp (original)
+++ cfe/trunk/test/Parser/cxx-class.cpp Mon Jul 23 00:45:25 2012
@@ -12,11 +12,15 @@
   int : 1, : 2;
 
 public:
+  void m0() {}; // ok, one extra ';' is permitted
+  void m1() {}
+  ; // ok, one extra ';' is permitted
   void m() {
     int l = 2;
-  }; // expected-warning{{extra ';' after function definition}}
+  };; // expected-warning{{extra ';' after member function definition}}
 
   template<typename T> void mt(T) { }
+  ;
   ; // expected-warning{{extra ';' inside a class}}
 
   virtual int vf() const volatile = 0;

Modified: cfe/trunk/test/Parser/cxx-decl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/cxx-decl.cpp?rev=160618&r1=160617&r2=160618&view=diff
==============================================================================
--- cfe/trunk/test/Parser/cxx-decl.cpp (original)
+++ cfe/trunk/test/Parser/cxx-decl.cpp Mon Jul 23 00:45:25 2012
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -verify -fsyntax-only -triple i386-linux %s
+// RUN: %clang_cc1 -verify -fsyntax-only -triple i386-linux -pedantic %s
 
 int x(*g); // expected-error {{use of undeclared identifier 'g'}}
 
@@ -44,7 +44,7 @@
   void foo() __asm__("baz");
 };
 
-enum { fooenum = 1 };
+enum { fooenum = 1, }; // expected-warning {{commas at the end of enumerator lists are a C++11 extension}}
 
 struct a {
   int Type : fooenum;
@@ -125,5 +125,3 @@
      // expected-error {{expected ';' after top level declarator}}
   
   int test6b;
-  
-  

Modified: cfe/trunk/test/Parser/cxx-extra-semi.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/cxx-extra-semi.cpp?rev=160618&r1=160617&r2=160618&view=diff
==============================================================================
--- cfe/trunk/test/Parser/cxx-extra-semi.cpp (original)
+++ cfe/trunk/test/Parser/cxx-extra-semi.cpp Mon Jul 23 00:45:25 2012
@@ -1,13 +1,26 @@
+// RUN: %clang_cc1 -fsyntax-only -pedantic -verify -DPEDANTIC %s
 // RUN: %clang_cc1 -fsyntax-only -Wextra-semi -verify %s
+// RUN: %clang_cc1 -fsyntax-only -Wextra-semi -verify -std=c++11 %s
 // RUN: cp %s %t
 // RUN: %clang_cc1 -x c++ -Wextra-semi -fixit %t
 // RUN: %clang_cc1 -x c++ -Wextra-semi -Werror %t
 
 class A {
   void A1();
-  void A2() { }; // expected-warning{{extra ';' after function definition}}
+  void A2() { };
+#ifndef PEDANTIC
+  // This warning is only produced if we specify -Wextra-semi, and not if only
+  // -pedantic is specified, since one semicolon is technically permitted.
+  // expected-warning at -4{{extra ';' after member function definition}}
+#endif
+  void A2b() { };; // expected-warning{{extra ';' after member function definition}}
   ; // expected-warning{{extra ';' inside a class}}
-  void A3() { };  ;; // expected-warning{{extra ';' after function definition}}
+  void A2c() { }
+  ;
+#ifndef PEDANTIC
+  // expected-warning at -2{{extra ';' after member function definition}}
+#endif
+  void A3() { };  ;; // expected-warning{{extra ';' after member function definition}}
   ;;;;;;; // expected-warning{{extra ';' inside a class}}
   ; // expected-warning{{extra ';' inside a class}}
   ; ;;		 ;  ;;; // expected-warning{{extra ';' inside a class}}
@@ -20,6 +33,9 @@
   int a2;; // expected-warning{{extra ';' inside a union}}
 };
 
-; // expected-warning{{extra ';' outside of a function}}
-; ;;// expected-warning{{extra ';' outside of a function}}
-
+;
+; ;;
+#if __cplusplus < 201103L
+// expected-warning at -3{{extra ';' outside of a function is a C++11 extension}}
+// expected-warning at -3{{extra ';' outside of a function is a C++11 extension}}
+#endif

Modified: cfe/trunk/test/Parser/cxx0x-decl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/cxx0x-decl.cpp?rev=160618&r1=160617&r2=160618&view=diff
==============================================================================
--- cfe/trunk/test/Parser/cxx0x-decl.cpp (original)
+++ cfe/trunk/test/Parser/cxx0x-decl.cpp Mon Jul 23 00:45:25 2012
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -verify -fsyntax-only -std=c++0x %s
+// RUN: %clang_cc1 -verify -fsyntax-only -std=c++11 -pedantic %s
 
 // Make sure we know these are legitimate commas and not typos for ';'.
 namespace Commas {
@@ -8,7 +8,7 @@
 }
 
 struct S {};
-enum E { e };
+enum E { e, };
 
 auto f() -> struct S {
   return S();
@@ -16,3 +16,12 @@
 auto g() -> enum E {
   return E();
 }
+
+class ExtraSemiAfterMemFn {
+  // Due to a peculiarity in the C++11 grammar, a deleted or defaulted function
+  // is permitted to be followed by either one or two semicolons.
+  void f() = delete // expected-error {{expected ';' after delete}}
+  void g() = delete; // ok
+  void h() = delete;; // ok
+  void i() = delete;;; // expected-warning {{extra ';' after member function definition}}
+};





More information about the cfe-commits mailing list