1999-05-19  Jason Merrill  <jason@yorick.cygnus.com>

	Implement anonymous structs.
	* cp-tree.h (ANON_AGGR_TYPE_P): Rename from ANON_UNION_TYPE_P.
	* class.c, decl.c, decl2.c, init.c, pt.c, search.c, typeck.c: Adjust.
	* class.c (finish_struct_1): Remove redundant check for anon struct.
	* decl.c (fixup_anonymous_aggr): Renamed from fixup_anonymous_union.
	(check_tag_decl): Check for anonymous struct here.
	* decl2.c (build_anon_union_vars): Catch anon struct at file scope.
	* init.c (sort_member_init, emit_base_init): Handle getting fields
	as well as names in current_member_init_list.
	(perform_member_init): Handle getting an anon aggr.
	* method.c (do_build_assign_ref): Don't descend into anon aggrs.
	(do_build_copy_constructor): Likewise.

Index: gcc-2.95.2/gcc/cp/class.c
===================================================================
RCS file: /homes/khan/src/CVSROOT/gcc-2.95.2/gcc/cp/class.c,v
retrieving revision 1.2
diff -u -3 -p -r1.2 class.c
--- gcc-2.95.2/gcc/cp/class.c	1999/11/05 06:11:44	1.2
+++ gcc-2.95.2/gcc/cp/class.c	1999/11/05 06:12:00
@@ -1336,7 +1336,7 @@ delete_duplicate_fields_1 (field, fields
   tree prev = 0;
   if (DECL_NAME (field) == 0)
     {
-      if (TREE_CODE (TREE_TYPE (field)) != UNION_TYPE)
+      if (! ANON_AGGR_TYPE_P (TREE_TYPE (field)))
 	return fields;
 
       for (x = TYPE_FIELDS (TREE_TYPE (field)); x; x = TREE_CHAIN (x))
@@ -1349,7 +1349,7 @@ delete_duplicate_fields_1 (field, fields
 	{
 	  if (DECL_NAME (x) == 0)
 	    {
-	      if (TREE_CODE (TREE_TYPE (x)) != UNION_TYPE)
+	      if (! ANON_AGGR_TYPE_P (TREE_TYPE (x)))
 		continue;
 	      TYPE_FIELDS (TREE_TYPE (x))
 		= delete_duplicate_fields_1 (field, TYPE_FIELDS (TREE_TYPE (x)));
@@ -2949,7 +2949,7 @@ finish_struct_anon (t)
 	continue;
 
       if (DECL_NAME (field) == NULL_TREE
-	  && TREE_CODE (TREE_TYPE (field)) == UNION_TYPE)
+	  && ANON_AGGR_TYPE_P (TREE_TYPE (field)))
 	{
 	  tree* uelt = &TYPE_FIELDS (TREE_TYPE (field));
 	  for (; *uelt; uelt = &TREE_CHAIN (*uelt))
@@ -3130,9 +3130,6 @@ finish_struct_1 (t, warn_anon)
   int empty = 1;
   int has_pointers = 0;
   tree inline_friends;
-
-  if (warn_anon && code != UNION_TYPE && ANON_AGGRNAME_P (TYPE_IDENTIFIER (t)))
-    pedwarn ("anonymous class type not used to declare any objects");
 
   if (TYPE_SIZE (t))
     {
Index: gcc-2.95.2/gcc/cp/cp-tree.h
===================================================================
RCS file: /homes/khan/src/CVSROOT/gcc-2.95.2/gcc/cp/cp-tree.h,v
retrieving revision 1.1.1.1
diff -u -3 -p -r1.1.1.1 cp-tree.h
--- gcc-2.95.2/gcc/cp/cp-tree.h	1999/11/05 01:09:46	1.1.1.1
+++ gcc-2.95.2/gcc/cp/cp-tree.h	1999/11/05 06:12:00
@@ -700,7 +700,7 @@ struct lang_type
       unsigned const_needs_init : 1;
       unsigned ref_needs_init : 1;
       unsigned has_const_assign_ref : 1;
-      unsigned anon_union : 1;
+      unsigned anon_aggr : 1;
 
       unsigned has_nonpublic_ctor : 2;
       unsigned has_nonpublic_assign_ref : 2;
@@ -1772,16 +1772,14 @@ extern int flag_new_for_scope;
    Just used to communicate formatting information to dbxout.c.  */
 #define DECL_OPERATOR(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.operator_attr)
 
-#define ANON_UNION_P(NODE) (DECL_NAME (NODE) == 0)
-
-/* Nonzero if TYPE is an anonymous union type.  We have to use a flag for
-   this because "A union for which objects or pointers are declared is not
-   an anonymous union" [class.union].  */
-#define ANON_UNION_TYPE_P(NODE)				\
+/* Nonzero if TYPE is an anonymous union or struct type.  We have to use a
+   flag for this because "A union for which objects or pointers are
+   declared is not an anonymous union" [class.union].  */
+#define ANON_AGGR_TYPE_P(NODE)				\
   (TYPE_LANG_SPECIFIC (NODE)				\
-   && TYPE_LANG_SPECIFIC (NODE)->type_flags.anon_union)
-#define SET_ANON_UNION_TYPE_P(NODE)				\
-  (TYPE_LANG_SPECIFIC (NODE)->type_flags.anon_union = 1)
+   && TYPE_LANG_SPECIFIC (NODE)->type_flags.anon_aggr)
+#define SET_ANON_AGGR_TYPE_P(NODE)			\
+  (TYPE_LANG_SPECIFIC (NODE)->type_flags.anon_aggr = 1)
 
 #define UNKNOWN_TYPE LANG_TYPE
 
@@ -2890,7 +2888,7 @@ extern int in_function_p			PROTO((void))
 extern void replace_defarg			PROTO((tree, tree));
 extern void print_other_binding_stack		PROTO((struct binding_level *));
 extern void revert_static_member_fn             PROTO((tree*, tree*, tree*));
-extern void fixup_anonymous_union               PROTO((tree));
+extern void fixup_anonymous_aggr               PROTO((tree));
 extern int check_static_variable_definition     PROTO((tree, tree));
 extern void push_local_binding                  PROTO((tree, tree, int));
 extern int push_class_binding                   PROTO((tree, tree));
Index: gcc-2.95.2/gcc/cp/decl.c
===================================================================
RCS file: /homes/khan/src/CVSROOT/gcc-2.95.2/gcc/cp/decl.c,v
retrieving revision 1.1.1.1
diff -u -3 -p -r1.1.1.1 decl.c
--- gcc-2.95.2/gcc/cp/decl.c	1999/11/05 01:09:46	1.1.1.1
+++ gcc-2.95.2/gcc/cp/decl.c	1999/11/05 06:12:01
@@ -4343,7 +4343,7 @@ pushdecl_class_level (x)
       if (TREE_CODE (x) == TYPE_DECL)
 	set_identifier_type_value (name, TREE_TYPE (x));
     }
-  else if (ANON_UNION_TYPE_P (TREE_TYPE (x)))
+  else if (ANON_AGGR_TYPE_P (TREE_TYPE (x)))
     {
       tree f;
 
@@ -7017,7 +7017,7 @@ define_function (name, type, function_co
    union type.)  */
 
 void
-fixup_anonymous_union (t)
+fixup_anonymous_aggr (t)
      tree t;
 {
   tree *q;
@@ -7104,12 +7104,15 @@ check_tag_decl (declspecs)
   /* Check for an anonymous union.  We're careful
      accessing TYPE_IDENTIFIER because some built-in types, like
      pointer-to-member types, do not have TYPE_NAME.  */
-  else if (t && TREE_CODE (t) == UNION_TYPE
+  else if (t && IS_AGGR_TYPE_CODE (TREE_CODE (t))
 	   && TYPE_NAME (t)
 	   && ANON_AGGRNAME_P (TYPE_IDENTIFIER (t)))
     {
       /* Anonymous unions are objects, so they can have specifiers.  */;
-      SET_ANON_UNION_TYPE_P (t);
+      SET_ANON_AGGR_TYPE_P (t);
+
+      if (TREE_CODE (t) != UNION_TYPE && pedantic && ! in_system_header)
+	pedwarn ("ISO C++ prohibits anonymous structs");
     }
 
   else if (ob_modifier)
@@ -7155,9 +7158,9 @@ shadow_tag (declspecs)
      union { ... } ;
      because there is no declarator after the union, the parser
      sends that declaration here.  */
-  if (t && ANON_UNION_TYPE_P (t))
+  if (t && ANON_AGGR_TYPE_P (t))
     {
-      fixup_anonymous_union (t);
+      fixup_anonymous_aggr (t);
 
       if (TYPE_FIELDS (t))
 	{
@@ -10087,7 +10090,7 @@ grokdeclarator (declarator, declspecs, d
   /* Static anonymous unions are dealt with here.  */
   if (staticp && decl_context == TYPENAME
       && TREE_CODE (declspecs) == TREE_LIST
-      && ANON_UNION_TYPE_P (TREE_VALUE (declspecs)))
+      && ANON_AGGR_TYPE_P (TREE_VALUE (declspecs)))
     decl_context = FIELD;
 
   /* Give error if `const,' `volatile,' `inline,' `friend,' or `virtual'
Index: gcc-2.95.2/gcc/cp/decl2.c
===================================================================
RCS file: /homes/khan/src/CVSROOT/gcc-2.95.2/gcc/cp/decl2.c,v
retrieving revision 1.1.1.1
diff -u -3 -p -r1.1.1.1 decl2.c
--- gcc-2.95.2/gcc/cp/decl2.c	1999/11/05 01:09:46	1.1.1.1
+++ gcc-2.95.2/gcc/cp/decl2.c	1999/11/05 06:12:01
@@ -893,10 +893,10 @@ grok_x_components (specs)
 
   /* The only case where we need to do anything additional here is an
      anonymous union field, e.g.: `struct S { union { int i; }; };'.  */
-  if (t == NULL_TREE || !ANON_UNION_TYPE_P (t))
+  if (t == NULL_TREE || !ANON_AGGR_TYPE_P (t))
     return;
 
-  fixup_anonymous_union (t);
+  fixup_anonymous_aggr (t);
   finish_member_declaration (build_lang_field_decl (FIELD_DECL,
 						    NULL_TREE,
 						    t)); 
@@ -2158,6 +2158,11 @@ build_anon_union_vars (anon_decl, elems,
   tree main_decl = NULL_TREE;
   tree field;
 
+  /* Rather than write the code to handle the non-union case,
+     just give an error.  */
+  if (TREE_CODE (type) != UNION_TYPE)
+    error ("anonymous struct not inside named type");
+
   for (field = TYPE_FIELDS (type); 
        field != NULL_TREE; 
        field = TREE_CHAIN (field))
@@ -2179,7 +2184,7 @@ build_anon_union_vars (anon_decl, elems,
 	cp_pedwarn_at ("protected member `%#D' in anonymous union", field);
 
       if (DECL_NAME (field) == NULL_TREE
-	  && TREE_CODE (TREE_TYPE (field)) == UNION_TYPE)
+	  && ANON_AGGR_TYPE_P (TREE_TYPE (field)))
 	{
 	  decl = build_anon_union_vars (field, elems, static_p, external_p);
 	  if (!decl)
@@ -2211,7 +2216,7 @@ build_anon_union_vars (anon_decl, elems,
 	TREE_ASM_WRITTEN (decl) = 1;
       
       if (DECL_NAME (field) == NULL_TREE
-	  && TREE_CODE (TREE_TYPE (field)) == UNION_TYPE)
+	  && ANON_AGGR_TYPE_P (TREE_TYPE (field)))
 	/* The remainder of the processing was already done in the
 	   recursive call.  */
 	continue;
Index: gcc-2.95.2/gcc/cp/init.c
===================================================================
RCS file: /homes/khan/src/CVSROOT/gcc-2.95.2/gcc/cp/init.c,v
retrieving revision 1.1.1.1
diff -u -3 -p -r1.1.1.1 init.c
--- gcc-2.95.2/gcc/cp/init.c	1999/11/05 01:09:46	1.1.1.1
+++ gcc-2.95.2/gcc/cp/init.c	1999/11/05 06:12:01
@@ -154,16 +154,25 @@ perform_member_init (member, name, init,
 
   expand_start_target_temps ();
 
-  if (TYPE_NEEDS_CONSTRUCTING (type)
-      || (init && TYPE_HAS_CONSTRUCTOR (type)))
+  decl = build_component_ref (current_class_ref, name, NULL_TREE, explicit);
+
+  /* Deal with this here, as we will get confused if we try to call the
+     assignment op for an anonymous union.  This can happen in a
+     synthesized copy constructor.  */
+  if (ANON_AGGR_TYPE_P (type))
+    {
+      init = build (INIT_EXPR, type, decl, TREE_VALUE (init));
+      TREE_SIDE_EFFECTS (init) = 1;
+      expand_expr_stmt (init);
+    }
+  else if (TYPE_NEEDS_CONSTRUCTING (type)
+	   || (init && TYPE_HAS_CONSTRUCTOR (type)))
     {
       /* Since `init' is already a TREE_LIST on the current_member_init_list,
 	 only build it into one if we aren't already a list.  */
       if (init != NULL_TREE && TREE_CODE (init) != TREE_LIST)
 	init = build_expr_list (NULL_TREE, init);
 
-      decl = build_component_ref (current_class_ref, name, NULL_TREE, explicit);
-
       if (explicit
 	  && TREE_CODE (type) == ARRAY_TYPE
 	  && init != NULL_TREE
@@ -186,7 +195,7 @@ perform_member_init (member, name, init,
 	      /* default-initialization.  */
 	      if (AGGREGATE_TYPE_P (type))
 		init = build (CONSTRUCTOR, type, NULL_TREE, NULL_TREE);
-	      else if (TREE_CODE (type) == REFERENCE_TYPE)
+ 	      else if (TREE_CODE (type) == REFERENCE_TYPE)
 		{
 		  cp_error ("default-initialization of `%#D', which has reference type",
 			    member);
@@ -216,8 +225,6 @@ perform_member_init (member, name, init,
 	 current_member_init_list.  */
       if (init || explicit)
 	{
-	  decl = build_component_ref (current_class_ref, name, NULL_TREE,
-				      explicit);
 	  expand_expr_stmt (build_modify_expr (decl, INIT_EXPR, init));
 	}
     }
@@ -275,16 +282,13 @@ sort_member_init (t)
 	    continue;
 	  name = TREE_PURPOSE (x);
 
-#if 0
-	  /* This happens in templates, since the IDENTIFIER is replaced
-             with the COMPONENT_REF in tsubst_expr.  */
-	  field = (TREE_CODE (name) == COMPONENT_REF
-		   ? TREE_OPERAND (name, 1) : IDENTIFIER_CLASS_VALUE (name));
-#else
-	  /* Let's find out when this happens.  */
-	  my_friendly_assert (TREE_CODE (name) != COMPONENT_REF, 348);
-	  field = IDENTIFIER_CLASS_VALUE (name);
-#endif
+	  if (TREE_CODE (name) == IDENTIFIER_NODE)
+	    field = IDENTIFIER_CLASS_VALUE (name);
+	  else
+	    {
+	      my_friendly_assert (TREE_CODE (name) == FIELD_DECL, 348); 
+	      field = name;
+	    }
 
 	  /* If one member shadows another, get the outermost one.  */
 	  if (TREE_CODE (field) == TREE_LIST)
@@ -612,15 +616,8 @@ emit_base_init (t, immediately)
 	  init = TREE_VALUE (mem_init_list);
 	  from_init_list = 1;
 
-#if 0
-	  if (TREE_CODE (name) == COMPONENT_REF)
-	    name = DECL_NAME (TREE_OPERAND (name, 1));
-#else
-	  /* Also see if it's ever a COMPONENT_REF here.  If it is, we
-	     need to do `expand_assignment (name, init, 0, 0);' and
-	     a continue.  */
-	  my_friendly_assert (TREE_CODE (name) != COMPONENT_REF, 349);
-#endif
+	  my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE
+			      || TREE_CODE (name) == FIELD_DECL, 349);
 	}
       else
 	{
@@ -649,9 +646,11 @@ emit_base_init (t, immediately)
 	{
 	  name = TREE_PURPOSE (mem_init_list);
 	  init = TREE_VALUE (mem_init_list);
-	  /* XXX: this may need the COMPONENT_REF operand 0 check if
-	     it turns out we actually get them.  */
-	  field = IDENTIFIER_CLASS_VALUE (name);
+
+	  if (TREE_CODE (name) == IDENTIFIER_NODE)
+	    field = IDENTIFIER_CLASS_VALUE (name);
+	  else
+	    field = name;
 
 	  /* If one member shadows another, get the outermost one.  */
 	  if (TREE_CODE (field) == TREE_LIST)
@@ -865,7 +864,7 @@ initializing_context (field)
 
   /* Anonymous union members can be initialized in the first enclosing
      non-anonymous union context.  */
-  while (t && ANON_UNION_TYPE_P (t))
+  while (t && ANON_AGGR_TYPE_P (t))
     t = TYPE_CONTEXT (t);
   return t;
 }
Index: gcc-2.95.2/gcc/cp/method.c
===================================================================
RCS file: /homes/khan/src/CVSROOT/gcc-2.95.2/gcc/cp/method.c,v
retrieving revision 1.1.1.1
diff -u -3 -p -r1.1.1.1 method.c
--- gcc-2.95.2/gcc/cp/method.c	1999/11/05 01:09:46	1.1.1.1
+++ gcc-2.95.2/gcc/cp/method.c	1999/11/05 06:12:01
@@ -2267,18 +2267,10 @@ do_build_copy_constructor (fndecl)
 		continue;
 	    }
 	  else if ((t = TREE_TYPE (field)) != NULL_TREE
-		   && ANON_UNION_TYPE_P (t)
+		   && ANON_AGGR_TYPE_P (t)
 		   && TYPE_FIELDS (t) != NULL_TREE)
-	    {
-	      do
-		{
-		  init = build (COMPONENT_REF, t, init, field);
-		  field = largest_union_member (t);
-		}
-	      while ((t = TREE_TYPE (field)) != NULL_TREE
-		     && ANON_UNION_TYPE_P (t)
-		     && TYPE_FIELDS (t) != NULL_TREE);
-	    }
+	    /* Just use the field; anonymous types can't have
+	       nontrivial copy ctors or assignment ops.  */;
 	  else
 	    continue;
 
@@ -2286,7 +2278,7 @@ do_build_copy_constructor (fndecl)
 	  init = build_tree_list (NULL_TREE, init);
 
 	  current_member_init_list
-	    = tree_cons (DECL_NAME (field), init, current_member_init_list);
+	    = tree_cons (field, init, current_member_init_list);
 	}
       current_member_init_list = nreverse (current_member_init_list);
       current_base_init_list = nreverse (current_base_init_list);
@@ -2375,19 +2367,10 @@ do_build_assign_ref (fndecl)
 		continue;
 	    }
 	  else if ((t = TREE_TYPE (field)) != NULL_TREE
-		   && ANON_UNION_TYPE_P (t)
+		   && ANON_AGGR_TYPE_P (t)
 		   && TYPE_FIELDS (t) != NULL_TREE)
-	    {
-	      do
-		{
-		  comp = build (COMPONENT_REF, t, comp, field);
-		  init = build (COMPONENT_REF, t, init, field);
-		  field = largest_union_member (t);
-		}
-	      while ((t = TREE_TYPE (field)) != NULL_TREE
-		     && ANON_UNION_TYPE_P (t)
-		     && TYPE_FIELDS (t) != NULL_TREE);
-	    }
+	    /* Just use the field; anonymous types can't have
+	       nontrivial copy ctors or assignment ops.  */;
 	  else
 	    continue;
 
Index: gcc-2.95.2/gcc/cp/pt.c
===================================================================
RCS file: /homes/khan/src/CVSROOT/gcc-2.95.2/gcc/cp/pt.c,v
retrieving revision 1.1.1.1
diff -u -3 -p -r1.1.1.1 pt.c
--- gcc-2.95.2/gcc/cp/pt.c	1999/11/05 01:09:46	1.1.1.1
+++ gcc-2.95.2/gcc/cp/pt.c	1999/11/05 06:12:01
@@ -4886,8 +4886,8 @@ instantiate_class_template (type)
   TYPE_PACKED (type) = TYPE_PACKED (pattern);
   TYPE_ALIGN (type) = TYPE_ALIGN (pattern);
   TYPE_FOR_JAVA (type) = TYPE_FOR_JAVA (pattern); /* For libjava's JArray<T> */
-  if (ANON_UNION_TYPE_P (pattern))
-    SET_ANON_UNION_TYPE_P (type);
+  if (ANON_AGGR_TYPE_P (pattern))
+    SET_ANON_AGGR_TYPE_P (type);
 
   /* We must copy the arguments to the permanent obstack since
      during the tsubst'ing below they may wind up in the
Index: gcc-2.95.2/gcc/cp/search.c
===================================================================
RCS file: /homes/khan/src/CVSROOT/gcc-2.95.2/gcc/cp/search.c,v
retrieving revision 1.1.1.1
diff -u -3 -p -r1.1.1.1 search.c
--- gcc-2.95.2/gcc/cp/search.c	1999/11/05 01:09:46	1.1.1.1
+++ gcc-2.95.2/gcc/cp/search.c	1999/11/05 06:12:01
@@ -534,7 +534,7 @@ lookup_field_1 (type, name)
 #endif /* GATHER_STATISTICS */
       my_friendly_assert (TREE_CODE_CLASS (TREE_CODE (field)) == 'd', 0);
       if (DECL_NAME (field) == NULL_TREE
-	  && TREE_CODE (TREE_TYPE (field)) == UNION_TYPE)
+	  && ANON_AGGR_TYPE_P (TREE_TYPE (field)))
 	{
 	  tree temp = lookup_field_1 (TREE_TYPE (field), name);
 	  if (temp)
@@ -610,7 +610,7 @@ context_for_name_lookup (decl)
      declared.  */ 
   tree context = DECL_REAL_CONTEXT (decl);
 
-  while (TYPE_P (context) && ANON_UNION_TYPE_P (context))
+  while (TYPE_P (context) && ANON_AGGR_TYPE_P (context))
     context = TYPE_CONTEXT (context);
   if (!context)
     context = global_namespace;
@@ -2939,7 +2939,7 @@ dfs_push_decls (binfo, data)
 	    && TREE_CODE (fields) != USING_DECL)
 	  setup_class_bindings (DECL_NAME (fields), /*type_binding_p=*/0);
 	else if (TREE_CODE (fields) == FIELD_DECL
-		 && ANON_UNION_TYPE_P (TREE_TYPE (fields)))
+		 && ANON_AGGR_TYPE_P (TREE_TYPE (fields)))
 	  dfs_push_decls (TYPE_BINFO (TREE_TYPE (fields)), data);
 	  
       method_vec = (CLASS_TYPE_P (type) 
@@ -3013,7 +3013,7 @@ dfs_unuse_fields (binfo, data)
 
       TREE_USED (fields) = 0;
       if (DECL_NAME (fields) == NULL_TREE
-	  && TREE_CODE (TREE_TYPE (fields)) == UNION_TYPE)
+	  && ANON_AGGR_TYPE_P (TREE_TYPE (fields)))
 	unuse_fields (TREE_TYPE (fields));
     }
 
Index: gcc-2.95.2/gcc/cp/typeck.c
===================================================================
RCS file: /homes/khan/src/CVSROOT/gcc-2.95.2/gcc/cp/typeck.c,v
retrieving revision 1.2
diff -u -3 -p -r1.2 typeck.c
--- gcc-2.95.2/gcc/cp/typeck.c	1999/11/05 06:11:44	1.2
+++ gcc-2.95.2/gcc/cp/typeck.c	1999/11/05 06:12:01
@@ -2011,7 +2011,7 @@ lookup_anon_field (t, type)
 
       /* Otherwise, it could be nested, search harder.  */
       if (DECL_NAME (field) == NULL_TREE
-	  && TREE_CODE (TREE_TYPE (field)) == UNION_TYPE)
+	  && ANON_AGGR_TYPE_P (TREE_TYPE (field)))
 	{
 	  tree subfield = lookup_anon_field (TREE_TYPE (field), type);
 	  if (subfield)
@@ -2221,7 +2221,7 @@ build_component_ref (datum, component, b
       tree context = DECL_FIELD_CONTEXT (field);
       tree base = context;
       while (!same_type_p (base, basetype) && TYPE_NAME (base)
-	     && ANON_UNION_TYPE_P (base))
+	     && ANON_AGGR_TYPE_P (base))
 	{
 	  base = TYPE_CONTEXT (base);
 	}
@@ -2251,7 +2251,7 @@ build_component_ref (datum, component, b
       basetype = base;
  
       /* Handle things from anon unions here...  */
-      if (TYPE_NAME (context) && ANON_UNION_TYPE_P (context))
+      if (TYPE_NAME (context) && ANON_AGGR_TYPE_P (context))
 	{
 	  tree subfield = lookup_anon_field (basetype, context);
 	  tree subdatum = build_component_ref (datum, subfield,
