From 254d2666e435e385c4b688dedb2bd4c2f33f0619 Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Mon, 28 Jan 2013 00:54:05 +0000 Subject: [PATCH] Add a -pedantic warning: an anonymous union within an anonymous union is not permitted in standard C++, despite being silently accepted by many (all?) major C++ implementations. llvm-svn: 173643 --- clang/include/clang/Basic/DiagnosticSemaKinds.td | 3 +++ clang/lib/Sema/SemaDecl.cpp | 6 ++++++ clang/test/SemaCXX/anonymous-union.cpp | 10 +++++----- clang/test/SemaCXX/constant-expression-cxx11.cpp | 4 ++-- 4 files changed, 16 insertions(+), 7 deletions(-) diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index fbaa2c5168f4..54b8c6f64c1d 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -5344,6 +5344,9 @@ def err_anonymous_record_with_type : Error< def ext_anonymous_record_with_type : Extension< "types declared in an anonymous %select{struct|union}0 are a Microsoft " "extension">, InGroup; +def ext_anonymous_record_with_anonymous_type : Extension< + "nested anonymous types are an extension">, + InGroup>; def err_anonymous_record_with_function : Error< "functions cannot be declared in an anonymous %select{struct|union}0">; def err_anonymous_record_with_static : Error< diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 136d12ebc317..a5f39a82f188 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -3198,6 +3198,12 @@ Decl *Sema::BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS, << (int)Record->isUnion(); Invalid = true; } + } else { + // This is an anonymous type definition within another anonymous type. + // This is a popular extension, provided by Plan9, MSVC and GCC, but + // not part of standard C++. + Diag(MemRecord->getLocation(), + diag::ext_anonymous_record_with_anonymous_type); } } else if (isa(*Mem)) { // Any access specifier is fine. diff --git a/clang/test/SemaCXX/anonymous-union.cpp b/clang/test/SemaCXX/anonymous-union.cpp index 2dd7ab86a88d..e77f52514733 100644 --- a/clang/test/SemaCXX/anonymous-union.cpp +++ b/clang/test/SemaCXX/anonymous-union.cpp @@ -9,7 +9,7 @@ struct X { int i; float f; - union { + union { // expected-warning{{nested anonymous types are an extension}} float f2; mutable double d; }; @@ -101,7 +101,7 @@ void g() { struct BadMembers { union { struct X { }; // expected-error {{types cannot be declared in an anonymous union}} - struct { int x; int y; } y; + struct { int x; int y; } y; // expected-warning{{nested anonymous types are an extension}} void f(); // expected-error{{functions cannot be declared in an anonymous union}} private: int x1; // expected-error{{anonymous union cannot contain a private data member}} @@ -128,7 +128,7 @@ namespace test4 { struct { // expected-warning{{anonymous structs are a GNU extension}} int s0; // expected-note {{declared private here}} double s1; // expected-note {{declared private here}} - union { + union { // expected-warning{{nested anonymous type}} int su0; // expected-note {{declared private here}} double su1; // expected-note {{declared private here}} }; @@ -136,7 +136,7 @@ namespace test4 { union { int u0; // expected-note {{declared private here}} double u1; // expected-note {{declared private here}} - struct { // expected-warning{{anonymous structs are a GNU extension}} + struct { // expected-warning{{anonymous structs are a GNU extension}} expected-warning{{nested anonymous type}} int us0; // expected-note {{declared private here}} double us1; // expected-note {{declared private here}} }; @@ -187,7 +187,7 @@ namespace PR8326 { private: const union { // expected-warning{{anonymous union cannot be 'const'}} - struct { // expected-warning{{anonymous structs are a GNU extension}} + struct { // expected-warning{{anonymous structs are a GNU extension}} expected-warning{{nested anonymous type}} T x; T y; }; diff --git a/clang/test/SemaCXX/constant-expression-cxx11.cpp b/clang/test/SemaCXX/constant-expression-cxx11.cpp index f504eb621f6c..8bb448cab030 100644 --- a/clang/test/SemaCXX/constant-expression-cxx11.cpp +++ b/clang/test/SemaCXX/constant-expression-cxx11.cpp @@ -1153,8 +1153,8 @@ namespace ConvertedConstantExpr { namespace IndirectField { struct S { struct { // expected-warning {{GNU extension}} - union { - struct { // expected-warning {{GNU extension}} + union { // expected-warning {{nested anonymous types are an extension}} + struct { // expected-warning {{GNU extension}} expected-warning {{nested anonymous types are an extension}} int a; int b; }; -- 2.34.1