On 5/25/26 11:07 AM, Jakub Jelinek wrote:
Hi!
Because we already reject anonymous struct members with non-trivial ctors,
dtors or copy assignment operator, I think we should also reject non-trivial
move assignment operator.
Hmm, I'm not sure about the motivation for the existing restrictions.
For a union they are mostly because you don't know which is the active
member, but anonymous structs don't have that problem.
But this is certainly consistent with do_build_copy_assign
else if (ANON_AGGR_TYPE_P (expr_type)
&& TYPE_FIELDS (expr_type) != NULL_TREE)
/* Just use the field; anonymous types can't have
nontrivial copy ctors or assignment ops or this
function would be deleted. */;
So I guess the current motivation is that removing the errors would be
more work. So, OK.
Jason
Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
2026-05-25 Jakub Jelinek <[email protected]>
* decl.cc (fixup_anonymous_aggr): Diagnose anonymous struct
with member with a type which has non-trivial move assignment
operator. Formatting fix.
* g++.dg/ext/anon-struct12.C: Expect another error.
--- gcc/cp/decl.cc.jj 2026-05-25 10:42:52.680441278 +0200
+++ gcc/cp/decl.cc 2026-05-25 11:34:28.402111542 +0200
@@ -6207,7 +6207,7 @@ fixup_anonymous_aggr (tree t)
}
}
}
- }
+ }
/* Splice all functions out of CLASSTYPE_MEMBER_VEC. */
vec<tree,va_gc>* vec = CLASSTYPE_MEMBER_VEC (t);
@@ -6250,6 +6250,9 @@ fixup_anonymous_aggr (tree t)
if (TYPE_HAS_COMPLEX_COPY_ASSIGN (type))
error ("member %q+#D with copy assignment operator "
"not allowed in anonymous aggregate", field);
+ if (TYPE_HAS_COMPLEX_MOVE_ASSIGN (type))
+ error ("member %q+#D with move assignment operator "
+ "not allowed in anonymous aggregate", field);
}
}
}
--- gcc/testsuite/g++.dg/ext/anon-struct12.C.jj 2026-05-25 10:42:52.683224452
+0200
+++ gcc/testsuite/g++.dg/ext/anon-struct12.C 2026-05-25 11:42:03.372731846
+0200
@@ -13,6 +13,7 @@ struct B { struct { int a = 1; long b; A
// { dg-error "member 'A B::<unnamed struct>::c' with constructor not allowed in anonymous
aggregate" "" { target *-*-* } .-1 }
// { dg-error "member 'A B::<unnamed struct>::c' with destructor not allowed in anonymous
aggregate" "" { target *-*-* } .-2 }
// { dg-error "member 'A B::<unnamed struct>::c' with copy assignment operator not allowed
in anonymous aggregate" "" { target *-*-* } .-3 }
+// { dg-error "member 'A B::<unnamed struct>::c' with move assignment operator not allowed in
anonymous aggregate" "" { target *-*-* } .-4 }
B d;
void foo (B &);
Jakub