aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authorPaolo Carlini <pcarlini@suse.de>2007-09-05 19:10:48 +0000
committerPaolo Carlini <paolo@gcc.gnu.org>2007-09-05 19:10:48 +0000
commit61fdc9d7460cf58d002cb91b5a3141dea69d9f48 (patch)
treea35f69825bbd15b17669ab413bf46bfb7fecb456 /gcc/cp
parent13678df87b8f2c1e23fb02b5f8e5fbbc9ce32260 (diff)
downloadgcc-61fdc9d7460cf58d002cb91b5a3141dea69d9f48.zip
gcc-61fdc9d7460cf58d002cb91b5a3141dea69d9f48.tar.gz
gcc-61fdc9d7460cf58d002cb91b5a3141dea69d9f48.tar.bz2
re PR c++/30302 (ICE with invalid member in anonymous struct)
/cp 2007-09-03 Paolo Carlini <pcarlini@suse.de> 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 <pcarlini@suse.de> PR c++/30302 * g++.dg/ext/anon-struct5.C: New. From-SVN: r128145
Diffstat (limited to 'gcc/cp')
-rw-r--r--gcc/cp/ChangeLog8
-rw-r--r--gcc/cp/class.c23
-rw-r--r--gcc/cp/semantics.c2
3 files changed, 28 insertions, 5 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index bfe5a316..f980792 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,11 @@
+2007-09-05 Paolo Carlini <pcarlini@suse.de>
+
+ 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 <jh@suse.cz>
* cp/sematics.c (expand_body): Remove unnecesary import_export_decl
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 4e051e3..9e0502f 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 054a83e..46789f7 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;