On Fri, 7 Jan 2022, Jakub Jelinek wrote:

> On Thu, Jan 06, 2022 at 10:44:09AM -0500, Patrick Palka via Gcc-patches wrote:
> > Fixed ever since r12-6188.
> > 
> >     PR c++/69681
> > 
> > gcc/testsuite/ChangeLog:
> > 
> >     * g++.dg/cpp0x/constexpr-compare2.C: New test.
> 
> Note, I've tested my
> https://gcc.gnu.org/pipermail/gcc-patches/2022-January/587745.html
> patch before you've committed this test, that patch makes it FAIL
> again.
> 
> The thing is that in address_compare now we make it all the way to
>       tree sz0 = DECL_SIZE_UNIT (base0);
>       tree sz1 = DECL_SIZE_UNIT (base1);
>       /* If sizes are unknown, e.g. VLA or not representable, punt.  */
>       if (!tree_fits_poly_int64_p (sz0) || !tree_fits_poly_int64_p (sz1))
>         return 2;
> which wants to check if one pointer is to a start of one object and
> another pointer to the end of another one.  But, base0 and base1
> are both FUNCTION_DECLs, and those seem to never have DECL_SIZE_UNIT
> set on them, whether the functions are external or defined locally.
> 
> We've already proven that base0 and base1 are different.  Can we
> with folding_initializer set (or even unset?) assume that if one
> or both of the bases are FUNCTION_DECLs they will compare unequal
> regardless if the other pointer is at the start or end of some
> variable?  For the !folding_initializer case, one thing is that
> while we've dealt with aliases visible to the compiler already and
> punted, there could again be aliases not visible to the compiler
> etc.  There is also a theoretical chance that .text section
> with some functions in it could be immediately followed by .rodata
> section with variables, but zero sized functions are rare and using
> address arithmetics to get to the end of a function isn't something
> we should support.  Some functions and variables could be also
> defined in assembly and could be adjacent...
> So at least limiting it to folding_initializer would be wise,
> but the question is what exactly should be valid and what should
> be invalid in C++.
> 
> So, thoughts on this?

Not totally sure but since pointer arithmetic on a function pointer
isn't a valid C++ constant expression, I suppose we could also restrict
ourselves to the case where both offsets are 0.  So probably returning
0 for FUNCTION_DECL if folding_initializer && ioff0 == 0 && ioff1 == 0
might be sufficient.

Then again, I don't see why we'd want to treat functions differently
from other decls when the offsets are 0, so perhaps we could relax
this to folding_initializer && ioff0 == 0 && ioff1 == 0.

> 
> > --- /dev/null
> > +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-compare2.C
> > @@ -0,0 +1,10 @@
> > +// PR c++/69681
> > +// { dg-do compile { target c++11 } }
> > +
> > +void f();
> > +void g();
> > +static_assert(f != g, "");
> > +
> > +#if __cpp_constexpr >= 201603L
> > +static_assert([]{} != []{}, "");
> > +#endif
> > -- 
> > 2.34.1.493.ge83ba647f7
> 
>       Jakub
> 
> 

Reply via email to