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