diff mbox series

[PR,c++/84602] ICE with anon-struct

Message ID 283ebc10-d9d9-188f-1030-bb9f99051f38@acm.org
State New
Headers show
Series [PR,c++/84602] ICE with anon-struct | expand

Commit Message

Nathan Sidwell Feb. 28, 2018, 12:30 p.m. UTC
This fixes an ICE with anon-struct.  When reimplementing this bit of 
name lookup, I relied on what the standard said and the completeness of 
the testsuite WRT extensions.  Silly me.

Anyway, we can just have the anon-struct lookup recurse to 
get_class_binding_direct, so simpler!

nathan
diff mbox series

Patch

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.

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

Index: cp/name-lookup.c
===================================================================
--- cp/name-lookup.c	(revision 258044)
+++ cp/name-lookup.c	(working copy)
@@ -1162,11 +1162,10 @@  fields_linear_search (tree klass, tree n
     {
       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 n
   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: cp/name-lookup.h
===================================================================
--- cp/name-lookup.h	(revision 258044)
+++ cp/name-lookup.h	(working copy)
@@ -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: testsuite/g++.dg/lookup/pr84602.C
===================================================================
--- testsuite/g++.dg/lookup/pr84602.C	(revision 0)
+++ testsuite/g++.dg/lookup/pr84602.C	(working copy)
@@ -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;