re PR c++/30302 (ICE with invalid member in anonymous struct)
authorPaolo Carlini <pcarlini@suse.de>
Wed, 5 Sep 2007 19:10:48 +0000 (19:10 +0000)
committerPaolo Carlini <paolo@gcc.gnu.org>
Wed, 5 Sep 2007 19:10:48 +0000 (19:10 +0000)
/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

gcc/cp/ChangeLog
gcc/cp/class.c
gcc/cp/semantics.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/ext/anon-struct5.C [new file with mode: 0644]

index bfe5a31..f980792 100644 (file)
@@ -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
index 4e051e3..9e0502f 100644 (file)
@@ -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);
index 054a83e..46789f7 100644 (file)
@@ -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;
 
index 897d6a9..242a363 100644 (file)
@@ -1,3 +1,8 @@
+2007-09-05  Paolo Carlini  <pcarlini@suse.de>
+
+       PR c++/30302
+       * g++.dg/ext/anon-struct5.C: New.
+
 2007-09-05  Uros Bizjak  <ubizjak@gmail.com>
 
        * 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 (file)
index 0000000..8b697cc
--- /dev/null
@@ -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; }
+};