From 61fdc9d7460cf58d002cb91b5a3141dea69d9f48 Mon Sep 17 00:00:00 2001 From: Paolo Carlini Date: Wed, 5 Sep 2007 19:10:48 +0000 Subject: [PATCH] re PR c++/30302 (ICE with invalid member in anonymous struct) /cp 2007-09-03 Paolo Carlini PR c++/30302 * semantics.c (finish_id_expression): Check that path != NULL_TREE before using TYPE_BINFO on it. * class.c (finish_struct_anon): Deal correctly with anonymous structs (vs unions, as GNU extension) in error messages. /testsuite 2007-09-03 Paolo Carlini PR c++/30302 * g++.dg/ext/anon-struct5.C: New. From-SVN: r128145 --- gcc/cp/ChangeLog | 8 ++++++++ gcc/cp/class.c | 23 +++++++++++++++++++---- gcc/cp/semantics.c | 2 +- gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/g++.dg/ext/anon-struct5.C | 13 +++++++++++++ 5 files changed, 46 insertions(+), 5 deletions(-) create mode 100644 gcc/testsuite/g++.dg/ext/anon-struct5.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index bfe5a316cbf..f98079256d9 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,11 @@ +2007-09-05 Paolo Carlini + + PR c++/30302 + * semantics.c (finish_id_expression): Use context_for_name_lookup + insted of DECL_CONTEXT, to see through anonymous structs and unions. + * class.c (finish_struct_anon): Deal correctly with anonymous + structs (vs unions, as GNU extension) in error messages. + 2007-09-05 Jan Hubicka * cp/sematics.c (expand_body): Remove unnecesary import_export_decl diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 4e051e3b688..9e0502fd1fb 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -2458,6 +2458,7 @@ finish_struct_anon (tree t) if (DECL_NAME (field) == NULL_TREE && ANON_AGGR_TYPE_P (TREE_TYPE (field))) { + bool is_union = TREE_CODE (TREE_TYPE (field)) == UNION_TYPE; tree elt = TYPE_FIELDS (TREE_TYPE (field)); for (; elt; elt = TREE_CHAIN (elt)) { @@ -2475,15 +2476,29 @@ finish_struct_anon (tree t) if (TREE_CODE (elt) != FIELD_DECL) { - pedwarn ("%q+#D invalid; an anonymous union can " - "only have non-static data members", elt); + if (is_union) + pedwarn ("%q+#D invalid; an anonymous union can " + "only have non-static data members", elt); + else + pedwarn ("%q+#D invalid; an anonymous struct can " + "only have non-static data members", elt); continue; } if (TREE_PRIVATE (elt)) - pedwarn ("private member %q+#D in anonymous union", elt); + { + if (is_union) + pedwarn ("private member %q+#D in anonymous union", elt); + else + pedwarn ("private member %q+#D in anonymous struct", elt); + } else if (TREE_PROTECTED (elt)) - pedwarn ("protected member %q+#D in anonymous union", elt); + { + if (is_union) + pedwarn ("protected member %q+#D in anonymous union", elt); + else + pedwarn ("protected member %q+#D in anonymous struct", elt); + } TREE_PRIVATE (elt) = TREE_PRIVATE (field); TREE_PROTECTED (elt) = TREE_PROTECTED (field); diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 054a83e6c30..46789f73565 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -2928,7 +2928,7 @@ finish_id_expression (tree id_expression, { if (DECL_P (decl) && DECL_NONLOCAL (decl) && DECL_CLASS_SCOPE_P (decl) - && DECL_CONTEXT (decl) != current_class_type) + && context_for_name_lookup (decl) != current_class_type) { tree path; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 897d6a9f25e..242a36365f4 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2007-09-05 Paolo Carlini + + PR c++/30302 + * g++.dg/ext/anon-struct5.C: New. + 2007-09-05 Uros Bizjak * gcc.dg/i386-cpuid.h: Remove. diff --git a/gcc/testsuite/g++.dg/ext/anon-struct5.C b/gcc/testsuite/g++.dg/ext/anon-struct5.C new file mode 100644 index 00000000000..8b697ccbca7 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/anon-struct5.C @@ -0,0 +1,13 @@ +// PR c++/30302 + +struct A +{ + struct { static int i; }; // { dg-error "prohibits anonymous structs|an anonymous struct" } + void foo() { i; } +}; + +struct B +{ + union { static int i; }; // { dg-error "an anonymous union|member of a union" } + void foo() { i; } +};