r359051 - Add missing diagnostic for anonymous struct/union definitions that don't

Richard Smith via cfe-commits cfe-commits at lists.llvm.org
Tue Apr 23 17:08:02 PDT 2019


Author: rsmith
Date: Tue Apr 23 17:08:02 2019
New Revision: 359051

URL: http://llvm.org/viewvc/llvm-project?rev=359051&view=rev
Log:
Add missing diagnostic for anonymous struct/union definitions that don't
introduce any names.

Modified:
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/test/Analysis/unions.cpp
    cfe/trunk/test/CXX/class/class.union/class.union.anon/p4.cpp
    cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p4.cpp
    cfe/trunk/test/CXX/drs/dr13xx.cpp
    cfe/trunk/test/CXX/drs/dr14xx.cpp
    cfe/trunk/test/CXX/drs/dr19xx.cpp
    cfe/trunk/test/CXX/module/module.interface/p3.cpp
    cfe/trunk/test/SemaCXX/anonymous-struct.cpp
    cfe/trunk/test/SemaCXX/anonymous-union.cpp
    cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp
    cfe/trunk/test/SemaCXX/cxx0x-deleted-default-ctor.cpp

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=359051&r1=359050&r2=359051&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Tue Apr 23 17:08:02 2019
@@ -4817,6 +4817,18 @@ Decl *Sema::BuildAnonymousStructOrUnion(
     Invalid = true;
   }
 
+  // C++ [dcl.dcl]p3:
+  //   [If there are no declarators], and except for the declaration of an
+  //   unnamed bit-field, the decl-specifier-seq shall introduce one or more
+  //   names into the program
+  // C++ [class.mem]p2:
+  //   each such member-declaration shall either declare at least one member
+  //   name of the class or declare at least one unnamed bit-field
+  //
+  // For C this is an error even for a named struct, and is diagnosed elsewhere.
+  if (getLangOpts().CPlusPlus && Record->field_empty())
+    Diag(DS.getBeginLoc(), diag::ext_no_declarators) << DS.getSourceRange();
+
   // Mock up a declarator.
   Declarator Dc(DS, DeclaratorContext::MemberContext);
   TypeSourceInfo *TInfo = GetTypeForDeclarator(Dc, S);

Modified: cfe/trunk/test/Analysis/unions.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/unions.cpp?rev=359051&r1=359050&r2=359051&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/unions.cpp (original)
+++ cfe/trunk/test/Analysis/unions.cpp Tue Apr 23 17:08:02 2019
@@ -36,7 +36,7 @@ namespace PR14054_original {
   struct ParseNode {
     union {
       struct {
-        union {};
+        union {}; // expected-warning {{does not declare anything}}
         Definition *lexdef;
       } name;
       class {

Modified: cfe/trunk/test/CXX/class/class.union/class.union.anon/p4.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/class/class.union/class.union.anon/p4.cpp?rev=359051&r1=359050&r2=359051&view=diff
==============================================================================
--- cfe/trunk/test/CXX/class/class.union/class.union.anon/p4.cpp (original)
+++ cfe/trunk/test/CXX/class/class.union/class.union.anon/p4.cpp Tue Apr 23 17:08:02 2019
@@ -2,7 +2,7 @@
 
 union U {
   int x = 0; // expected-note {{previous initialization is here}}
-  union {};
+  union {}; // expected-warning {{does not declare anything}}
   union {
     int z;
     int y = 1; // expected-error {{initializing multiple members of union}}

Modified: cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p4.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p4.cpp?rev=359051&r1=359050&r2=359051&view=diff
==============================================================================
--- cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p4.cpp (original)
+++ cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p4.cpp Tue Apr 23 17:08:02 2019
@@ -181,8 +181,8 @@ union Empty {
 } constexpr empty1;
 
 struct EmptyVariant {
-  union {};
-  struct {};
+  union {}; // expected-warning {{does not declare anything}}
+  struct {}; // expected-warning {{does not declare anything}}
   constexpr EmptyVariant() {} // ok
 } constexpr empty2;
 

Modified: cfe/trunk/test/CXX/drs/dr13xx.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/drs/dr13xx.cpp?rev=359051&r1=359050&r2=359051&view=diff
==============================================================================
--- cfe/trunk/test/CXX/drs/dr13xx.cpp (original)
+++ cfe/trunk/test/CXX/drs/dr13xx.cpp Tue Apr 23 17:08:02 2019
@@ -272,7 +272,7 @@ namespace dr1359 { // dr1359: 3.5
   union A { constexpr A() = default; };
   union B { constexpr B() = default; int a; }; // expected-error {{not constexpr}} expected-note 2{{candidate}}
   union C { constexpr C() = default; int a, b; }; // expected-error {{not constexpr}} expected-note 2{{candidate}}
-  struct X { constexpr X() = default; union {}; };
+  struct X { constexpr X() = default; union {}; }; // expected-error {{does not declare anything}}
   struct Y { constexpr Y() = default; union { int a; }; }; // expected-error {{not constexpr}} expected-note 2{{candidate}}
 
   constexpr A a = A();

Modified: cfe/trunk/test/CXX/drs/dr14xx.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/drs/dr14xx.cpp?rev=359051&r1=359050&r2=359051&view=diff
==============================================================================
--- cfe/trunk/test/CXX/drs/dr14xx.cpp (original)
+++ cfe/trunk/test/CXX/drs/dr14xx.cpp Tue Apr 23 17:08:02 2019
@@ -13,22 +13,22 @@ namespace dr1460 { // dr1460: 3.5
 #if __cplusplus >= 201103L
   namespace DRExample {
     union A {
-      union {};
-      union {};
+      union {}; // expected-error {{does not declare anything}}
+      union {}; // expected-error {{does not declare anything}}
       constexpr A() {}
     };
     constexpr A a = A();
 
     union B {
-      union {};
-      union {};
+      union {}; // expected-error {{does not declare anything}}
+      union {}; // expected-error {{does not declare anything}}
       constexpr B() = default;
     };
     constexpr B b = B();
 
     union C {
-      union {};
-      union {};
+      union {}; // expected-error {{does not declare anything}}
+      union {}; // expected-error {{does not declare anything}}
     };
     constexpr C c = C();
 #if __cplusplus > 201103L
@@ -40,7 +40,7 @@ namespace dr1460 { // dr1460: 3.5
   union A {};
   union B { int n; }; // expected-note +{{here}}
   union C { int n = 0; };
-  struct D { union {}; };
+  struct D { union {}; }; // expected-error {{does not declare anything}}
   struct E { union { int n; }; }; // expected-note +{{here}}
   struct F { union { int n = 0; }; };
 
@@ -66,7 +66,7 @@ namespace dr1460 { // dr1460: 3.5
     union A { constexpr A() = default; };
     union B { int n; constexpr B() = default; }; // expected-error {{not constexpr}}
     union C { int n = 0; constexpr C() = default; };
-    struct D { union {}; constexpr D() = default; };
+    struct D { union {}; constexpr D() = default; }; // expected-error {{does not declare anything}}
     struct E { union { int n; }; constexpr E() = default; }; // expected-error {{not constexpr}}
     struct F { union { int n = 0; }; constexpr F() = default; };
 

Modified: cfe/trunk/test/CXX/drs/dr19xx.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/drs/dr19xx.cpp?rev=359051&r1=359050&r2=359051&view=diff
==============================================================================
--- cfe/trunk/test/CXX/drs/dr19xx.cpp (original)
+++ cfe/trunk/test/CXX/drs/dr19xx.cpp Tue Apr 23 17:08:02 2019
@@ -84,6 +84,7 @@ namespace dr1940 { // dr1940: yes
 static union {
   static_assert(true, "");  // ok
   static_assert(false, ""); // expected-error {{static_assert failed}}
+  int not_empty;
 };
 #endif
 }

Modified: cfe/trunk/test/CXX/module/module.interface/p3.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/module/module.interface/p3.cpp?rev=359051&r1=359050&r2=359051&view=diff
==============================================================================
--- cfe/trunk/test/CXX/module/module.interface/p3.cpp (original)
+++ cfe/trunk/test/CXX/module/module.interface/p3.cpp Tue Apr 23 17:08:02 2019
@@ -15,15 +15,15 @@ export { // expected-note 3{{export bloc
   using namespace A; // expected-error {{ISO C++20 does not permit using directive to be exported}}
 }
 
-export struct {}; // expected-error {{must be class member}} expected-error {{GNU extension}}
+export struct {}; // expected-error {{must be class member}} expected-error {{GNU extension}} expected-error {{does not declare anything}}
 export struct {} struct_;
-export union {}; // expected-error {{must be declared 'static'}}
+export union {}; // expected-error {{must be declared 'static'}} expected-error {{does not declare anything}}
 export union {} union_;
 export enum {}; // expected-error {{does not declare anything}}
 export enum {} enum_;
 export enum E : int;
 export typedef int; // expected-error {{typedef requires a name}}
-export static union {}; // FIXME: this declaration is ill-formed even without the 'export'
+export static union {}; // expected-error {{does not declare anything}}
 export asm(""); // expected-error {{asm declaration cannot be exported}}
 export namespace B = A;
 export using A::ns_mem;

Modified: cfe/trunk/test/SemaCXX/anonymous-struct.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/anonymous-struct.cpp?rev=359051&r1=359050&r2=359051&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/anonymous-struct.cpp (original)
+++ cfe/trunk/test/SemaCXX/anonymous-struct.cpp Tue Apr 23 17:08:02 2019
@@ -9,7 +9,7 @@ struct S {
 #endif
 };
 
-struct { // expected-error {{anonymous structs and classes must be class members}}
+struct { // expected-error {{anonymous structs and classes must be class members}} expected-warning {{does not declare anything}}
 };
 
 struct E {
@@ -19,7 +19,7 @@ struct E {
     // expected-error at -2 {{anonymous struct member 'x' has a non-trivial default constructor}}
 #endif
   };
-  static struct {
+  static struct { // expected-warning {{does not declare anything}}
   };
   class {
     int anon_priv_field; // expected-error {{anonymous struct cannot contain a private data member}}

Modified: cfe/trunk/test/SemaCXX/anonymous-union.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/anonymous-union.cpp?rev=359051&r1=359050&r2=359051&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/anonymous-union.cpp (original)
+++ cfe/trunk/test/SemaCXX/anonymous-union.cpp Tue Apr 23 17:08:02 2019
@@ -81,7 +81,7 @@ union { // expected-error{{anonymous uni
 };
 
 extern "C++" {
-union { }; // expected-error{{anonymous unions at namespace or global scope must be declared 'static'}}
+union { int extern_cxx; }; // expected-error{{anonymous unions at namespace or global scope must be declared 'static'}}
 }
 
 static union {

Modified: cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp?rev=359051&r1=359050&r2=359051&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp (original)
+++ cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp Tue Apr 23 17:08:02 2019
@@ -2146,7 +2146,7 @@ namespace InheritedCtor {
   struct B : A { int n; using A::A; }; // expected-note {{here}}
   constexpr B b(0); // expected-error {{constant expression}} expected-note {{derived class}}
 
-  struct C : A { using A::A; struct { union { int n, m = 0; }; union { int a = 0; }; int k = 0; }; struct {}; union {}; }; // expected-warning 4{{extension}}
+  struct C : A { using A::A; struct { union { int n, m = 0; }; union { int a = 0; }; int k = 0; }; struct {}; union {}; }; // expected-warning 6{{}}
   constexpr C c(0);
 
   struct D : A {

Modified: cfe/trunk/test/SemaCXX/cxx0x-deleted-default-ctor.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx0x-deleted-default-ctor.cpp?rev=359051&r1=359050&r2=359051&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/cxx0x-deleted-default-ctor.cpp (original)
+++ cfe/trunk/test/SemaCXX/cxx0x-deleted-default-ctor.cpp Tue Apr 23 17:08:02 2019
@@ -121,11 +121,11 @@ late_delete::late_delete() = default; //
 
 // See also rdar://problem/8125400.
 namespace empty {
-  static union {};
-  static union { union {}; };
-  static union { struct {}; };
-  static union { union { union {}; }; };
-  static union { union { struct {}; }; };
-  static union { struct { union {}; }; };
-  static union { struct { struct {}; }; };
+  static union {}; // expected-warning {{does not declare anything}}
+  static union { union {}; }; // expected-warning {{does not declare anything}}
+  static union { struct {}; }; // expected-warning {{does not declare anything}}
+  static union { union { union {}; }; }; // expected-warning {{does not declare anything}}
+  static union { union { struct {}; }; }; // expected-warning {{does not declare anything}}
+  static union { struct { union {}; }; }; // expected-warning {{does not declare anything}}
+  static union { struct { struct {}; }; }; // expected-warning {{does not declare anything}}
 }




More information about the cfe-commits mailing list