On Tue, 28 Sep 2021, Jakub Jelinek wrote: > On Tue, Sep 28, 2021 at 09:49:11AM -0400, Patrick Palka via Gcc-patches wrote: > > > --- gcc/cp/method.c.jj 2021-09-15 08:55:37.563497558 +0200 > > > +++ gcc/cp/method.c 2021-09-27 13:48:12.139271830 +0200 > > > @@ -3160,8 +3160,11 @@ defaulted_late_check (tree fn) > > > if (kind == sfk_comparison) > > > { > > > /* If the function was declared constexpr, check that the > > > definition > > > - qualifies. Otherwise we can define the function lazily. */ > > > - if (DECL_DECLARED_CONSTEXPR_P (fn) && !DECL_INITIAL (fn)) > > > + qualifies. Otherwise we can define the function lazily. > > > + Don't do this if the class type is still incomplete. */ > > > + if (DECL_DECLARED_CONSTEXPR_P (fn) > > > + && !DECL_INITIAL (fn) > > > + && COMPLETE_TYPE_P (ctx)) > > > { > > > > According to the function comment for defaulted_late_check, won't > > COMPLETE_TYPE_P (ctx) always be false here? > > It is true in the call from the following hunk. > The function comment at least to me doesn't imply it is always called on > incomplete types, and defaultable_fn_check also calls it.
Ah yeah, sorry for the noise, I misunderstood the function comment. On a related note I think 'ctx' can also be a NAMESPACE_DECL here in the case of a defaulted non-member operator<=> (as in the below), for which I'd expect the added COMPLETE_TYPE_P check to crash, but it looks like in this case DECL_INITIAL is error_mark_node instead of NULL_TREE so a crash is averted. If anyone else was wondering... struct A { friend constexpr bool operator==(const A&, const A&); }; constexpr bool operator==(const A&, const A&) = default; > > > > > /* Prevent GC. */ > > > function_depth++; > > > --- gcc/cp/class.c.jj 2021-09-03 09:46:28.801428380 +0200 > > > +++ gcc/cp/class.c 2021-09-27 14:07:03.465562255 +0200 > > > @@ -7467,7 +7467,14 @@ finish_struct_1 (tree t) > > > for any static member objects of the type we're working on. */ > > > for (x = TYPE_FIELDS (t); x; x = DECL_CHAIN (x)) > > > if (DECL_DECLARES_FUNCTION_P (x)) > > > - DECL_IN_AGGR_P (x) = false; > > > + { > > > + /* Synthetize constexpr defaulted comparisons. */ > > > + if (!DECL_ARTIFICIAL (x) > > > + && DECL_DEFAULTED_IN_CLASS_P (x) > > > + && special_function_p (x) == sfk_comparison) > > > + defaulted_late_check (x); > > > + DECL_IN_AGGR_P (x) = false; > > > + } > > > else if (VAR_P (x) && TREE_STATIC (x) > > > && TREE_TYPE (x) != error_mark_node > > > && same_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (x)), t)) > > Jakub > >