[PR c++/84602] ICE with anon-struct
authorNathan Sidwell <nathan@gcc.gnu.org>
Wed, 28 Feb 2018 12:32:10 +0000 (12:32 +0000)
committerNathan Sidwell <nathan@gcc.gnu.org>
Wed, 28 Feb 2018 12:32:10 +0000 (12:32 +0000)
https://gcc.gnu.org/ml/gcc-patches/2018-02/msg01577.html
PR c++/84602
* name-lookup.h (search_anon_aggr): Add defaulted WANT_TYPE arg.
* name-lookup.c (fields_linear_search): Look in an anon-aggr
regardless of want_type.
(search_anon_aggr): Just use get_class_binding_direct.

PR c++/84602
* g++.dg/lookup/pr84602.C: New.

From-SVN: r258060

gcc/cp/ChangeLog
gcc/cp/name-lookup.c
gcc/cp/name-lookup.h
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/lookup/pr84602.C [new file with mode: 0644]

index 0adbc3f93c6321ab98c306416df613065b47f678..e2d88dcf240ad4c4b2d9c38eb66614985fb71730 100644 (file)
@@ -1,3 +1,11 @@
+2018-02-28  Nathan Sidwell  <nathan@acm.org>
+
+       PR c++/84602
+       * name-lookup.h (search_anon_aggr): Add defaulted WANT_TYPE arg.
+       * name-lookup.c (fields_linear_search): Look in an anon-aggr
+       regardless of want_type.
+       (search_anon_aggr): Just use get_class_binding_direct.
+
 2018-02-28  Jakub Jelinek  <jakub@redhat.com>
 
        * decl.c (cp_finish_decomp): Don't adjust eltscnt when calling
index c61f01c4f88bec01d41b901021ff0223ad257434..20db0f427dafa16052fcc28763ab618acc1768d0 100644 (file)
@@ -1162,11 +1162,10 @@ fields_linear_search (tree klass, tree name, bool want_type)
     {
       tree decl = fields;
 
-      if (!want_type
-         && TREE_CODE (decl) == FIELD_DECL
+      if (TREE_CODE (decl) == FIELD_DECL
          && ANON_AGGR_TYPE_P (TREE_TYPE (decl)))
        {
-         if (tree temp = search_anon_aggr (TREE_TYPE (decl), name))
+         if (tree temp = search_anon_aggr (TREE_TYPE (decl), name, want_type))
            return temp;
        }
 
@@ -1191,26 +1190,17 @@ fields_linear_search (tree klass, tree name, bool want_type)
   return NULL_TREE;
 }
 
-/* Look for NAME field inside of anonymous aggregate ANON.  */
+/* Look for NAME member inside of anonymous aggregate ANON.  Although
+   such things should only contain FIELD_DECLs, we check that too
+   late, and would give very confusing errors if we weren't
+   permissive here.  */
 
 tree
-search_anon_aggr (tree anon, tree name)
+search_anon_aggr (tree anon, tree name, bool want_type)
 {
   gcc_assert (COMPLETE_TYPE_P (anon));
-  tree ret;
-         
-  if (vec<tree, va_gc> *member_vec = CLASSTYPE_MEMBER_VEC (anon))
-    ret = member_vec_linear_search (member_vec, name);
-  else
-    ret = fields_linear_search (anon, name, false);
-
-  if (ret)
-    {
-      /* Anon members can only contain fields.  */
-      gcc_assert (!STAT_HACK_P (ret) && !DECL_DECLARES_TYPE_P (ret));
-      return ret;
-    }
-  return NULL_TREE;
+  tree ret = get_class_binding_direct (anon, name, want_type);
+  return ret;
 }
 
 /* Look for NAME as an immediate member of KLASS (including
index fe15136b227fc84b92a6c51cd4e8fe3185046be4..8c587d3528bda70babd640ce408f56b7dca16935 100644 (file)
@@ -307,7 +307,7 @@ extern void pop_decl_namespace (void);
 extern void do_namespace_alias (tree, tree);
 extern tree do_class_using_decl (tree, tree);
 extern tree lookup_arg_dependent (tree, tree, vec<tree, va_gc> *);
-extern tree search_anon_aggr (tree, tree);
+extern tree search_anon_aggr (tree, tree, bool = false);
 extern tree get_class_binding_direct (tree, tree, int type_or_fns = -1);
 extern tree get_class_binding (tree, tree, int type_or_fns = -1);
 extern tree *find_member_slot (tree klass, tree name);
index c036308c6e53caec6a793f33370829b1667221e4..252a33a00d43f0ccd04ad54b0550be7d3a570fdd 100644 (file)
@@ -1,3 +1,8 @@
+2018-02-28  Nathan Sidwell  <nathan@acm.org>
+
+       PR c++/84602
+       * g++.dg/lookup/pr84602.C: New.
+
 2018-02-28  Jakub Jelinek  <jakub@redhat.com>
 
        PR c++/83871
@@ -5,7 +10,8 @@
        * g++.dg/ext/attr-warning.C: Remove -fdump-tree-optimized from
        dg-options.
        * g++.dg/ext/attr-nonnull.C: Likewise.
-       * g++.dg/ext/attr-noinline.C: Fix syntax in scan-tree-dump-not directives.
+       * g++.dg/ext/attr-noinline.C: Fix syntax in scan-tree-dump-not
+       directives.
        * g++.dg/ext/attr-noinline-2.C: Likewise.
        * g++.dg/ext/attr-noreturn-2.C: Use -fdump-tree-optimized instead of
        -fdump-tree-eh in dg-options.
diff --git a/gcc/testsuite/g++.dg/lookup/pr84602.C b/gcc/testsuite/g++.dg/lookup/pr84602.C
new file mode 100644 (file)
index 0000000..d388ae0
--- /dev/null
@@ -0,0 +1,32 @@
+// PR c++/84602 ICE
+// { dg-additional-options "-fpermissive" }
+
+struct X {
+  union {
+    class a; // { dg-warning "can only have" }
+  };
+  a *b;
+};
+X::a *a;
+
+struct Y {
+  union {
+    class a; // { dg-warning "can only have" }
+    int a;
+  };
+  class a *b;
+};
+
+class Y::a *y;
+
+struct Z {
+  union {
+    // Force MEMBER_VEC creation
+    int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10;
+    class a; // { dg-warning "can only have" }
+    int a;
+  };
+  class a *b;
+};
+
+class Z::a *z;