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
> 
> 

Reply via email to