diff mbox series

[committed] c++: Add testcase for recently fixed PR [PR69681]

Message ID 20220106154409.2238665-1-ppalka@redhat.com
State New
Headers show
Series [committed] c++: Add testcase for recently fixed PR [PR69681] | expand

Commit Message

Patrick Palka Jan. 6, 2022, 3:44 p.m. UTC
Fixed ever since r12-6188.

	PR c++/69681

gcc/testsuite/ChangeLog:

	* g++.dg/cpp0x/constexpr-compare2.C: New test.
---
 gcc/testsuite/g++.dg/cpp0x/constexpr-compare2.C | 10 ++++++++++
 1 file changed, 10 insertions(+)
 create mode 100644 gcc/testsuite/g++.dg/cpp0x/constexpr-compare2.C

Comments

Jakub Jelinek Jan. 7, 2022, 10:22 a.m. UTC | #1
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?

> --- /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
Patrick Palka Jan. 7, 2022, 3:12 p.m. UTC | #2
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
> 
>
diff mbox series

Patch

diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-compare2.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-compare2.C
new file mode 100644
index 00000000000..b1bc4720805
--- /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