From a6659b552d17639829425eef63e5a9569049f371 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Tue, 25 Feb 2014 16:18:19 -0500 Subject: [PATCH] decl2.c (finish_static_data_member_decl): Diagnose static data member in unnamed class. * decl2.c (finish_static_data_member_decl): Diagnose static data member in unnamed class. From-SVN: r208156 --- gcc/cp/ChangeLog | 4 ++++ gcc/cp/class.c | 4 +++- gcc/cp/decl2.c | 11 +++++++++++ gcc/testsuite/g++.dg/ext/anon-struct5.C | 4 ++-- gcc/testsuite/g++.dg/ext/anon-struct6.C | 2 +- gcc/testsuite/g++.dg/parse/unnamed1.C | 6 ++++++ 6 files changed, 27 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/g++.dg/parse/unnamed1.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 393b213..9e3a63e 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,9 @@ 2014-02-25 Jason Merrill + * decl2.c (finish_static_data_member_decl): Diagnose static data + member in unnamed class. + * class.c (finish_struct_anon_r): Avoid redundant diagnostic. + PR lto/53808 * class.c (clone_function_decl): Call note_vague_linkage_fn for defaulted virtual dtor. diff --git a/gcc/cp/class.c b/gcc/cp/class.c index e861e4d..f61dc9d 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -2851,7 +2851,9 @@ finish_struct_anon_r (tree field, bool complain) if (TREE_CODE (elt) != FIELD_DECL) { - if (complain) + /* We already complained about static data members in + finish_static_data_member_decl. */ + if (complain && TREE_CODE (elt) != VAR_DECL) { if (is_union) permerror (input_location, diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 35707a0..f512541 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -802,6 +802,17 @@ finish_static_data_member_decl (tree decl, && !DECL_TEMPLATE_INSTANTIATION (decl)) permerror (input_location, "local class %q#T shall not have static data member %q#D", current_class_type, decl); + else + for (tree t = current_class_type; TYPE_P (t); + t = CP_TYPE_CONTEXT (t)) + if (TYPE_ANONYMOUS_P (t)) + { + if (permerror (DECL_SOURCE_LOCATION (decl), + "static data member %qD in unnamed class", decl)) + inform (DECL_SOURCE_LOCATION (TYPE_NAME (t)), + "unnamed class defined here"); + break; + } DECL_IN_AGGR_P (decl) = 1; diff --git a/gcc/testsuite/g++.dg/ext/anon-struct5.C b/gcc/testsuite/g++.dg/ext/anon-struct5.C index 8b697cc..ec02225 100644 --- a/gcc/testsuite/g++.dg/ext/anon-struct5.C +++ b/gcc/testsuite/g++.dg/ext/anon-struct5.C @@ -2,12 +2,12 @@ struct A { - struct { static int i; }; // { dg-error "prohibits anonymous structs|an anonymous struct" } + struct { static int i; }; // { dg-error "prohibits anonymous structs|an anonymous struct|unnamed class" } void foo() { i; } }; struct B { - union { static int i; }; // { dg-error "an anonymous union|member of a union" } + union { static int i; }; // { dg-error "an anonymous union|member of a union|unnamed class" } void foo() { i; } }; diff --git a/gcc/testsuite/g++.dg/ext/anon-struct6.C b/gcc/testsuite/g++.dg/ext/anon-struct6.C index 11a7bbd..66d4b32 100644 --- a/gcc/testsuite/g++.dg/ext/anon-struct6.C +++ b/gcc/testsuite/g++.dg/ext/anon-struct6.C @@ -4,7 +4,7 @@ struct A { struct { // { dg-error "anonymous struct cannot have function members" } - struct { static int i; }; // { dg-error "prohibits anonymous structs|non-static data members" } + struct { static int i; }; // { dg-error "prohibits anonymous structs|non-static data members|unnamed class" } void foo() { i; } }; // { dg-error "prohibits anonymous structs" } }; diff --git a/gcc/testsuite/g++.dg/parse/unnamed1.C b/gcc/testsuite/g++.dg/parse/unnamed1.C new file mode 100644 index 0000000..f5972f1 --- /dev/null +++ b/gcc/testsuite/g++.dg/parse/unnamed1.C @@ -0,0 +1,6 @@ +// 9.4.2/4: Unnamed classes and classes contained directly or indirectly +// within unnamed classes shall not contain static data members. + +typedef struct { // { dg-message "unnamed" } + static int i; // { dg-error "static data member" } +} A; -- 2.7.4