On Thu, 14 Mar 2019, Jakub Jelinek wrote:
> Hi!
>
> As mentioned in the PR, r267272 added STRIP_ANY_LOCATION_WRAPPERS
> at the start of operand_equal_p, but has not updated inchash::add_expr
> which needs to follow what operand_equal_p does, so that if two trees
> compare equal, they get the same hash value.
> For location wrappers at the outermost level we wouldn't even try to
> verify it, as they would be stripped before checking the hashes,
> and in the usual case it wouldn't make a difference because if not
> OEP_ADDRESS_OF STRIP_NOPS strips also the location wrappers.
> But if OEP_ADDRESS_OF is set and we have e.g. a location wrapper in one
> of the operands and not in the other one (the ICE is on
> >, field>>>
> vs.
> , field>>>
> which compares equal but has different hashes), then we need to make sure
> they have the same hash.
>
> The following patch fixes that and also moves the operand_equal_p location
> wrapper stripping after the hash value computation code to check the hashes
> in all cases.
>
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
OK.
Richard.
> 2019-03-14 Jakub Jelinek
>
> PR c++/89709
> * tree.c (inchash::add_expr): Strip any location wrappers.
> * fold-const.c (operand_equal_p): Move stripping of location wrapper
> after hash verification.
>
> * g++.dg/cpp0x/constexpr-89709.C: New test.
>
> --- gcc/tree.c.jj 2019-03-11 22:56:45.511835239 +0100
> +++ gcc/tree.c2019-03-14 11:39:55.898838708 +0100
> @@ -7743,6 +7743,8 @@ add_expr (const_tree t, inchash::hash &h
>return;
> }
>
> + STRIP_ANY_LOCATION_WRAPPER (t);
> +
>if (!(flags & OEP_ADDRESS_OF))
> STRIP_NOPS (t);
>
> --- gcc/fold-const.c.jj 2019-03-05 10:03:09.818780210 +0100
> +++ gcc/fold-const.c 2019-03-14 11:47:12.117791365 +0100
> @@ -2942,9 +2942,6 @@ combine_comparisons (location_t loc,
> int
> operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags)
> {
> - STRIP_ANY_LOCATION_WRAPPER (arg0);
> - STRIP_ANY_LOCATION_WRAPPER (arg1);
> -
>/* When checking, verify at the outermost operand_equal_p call that
> if operand_equal_p returns non-zero then ARG0 and ARG1 has the same
> hash value. */
> @@ -2967,6 +2964,9 @@ operand_equal_p (const_tree arg0, const_
> return 0;
> }
>
> + STRIP_ANY_LOCATION_WRAPPER (arg0);
> + STRIP_ANY_LOCATION_WRAPPER (arg1);
> +
>/* If either is ERROR_MARK, they aren't equal. */
>if (TREE_CODE (arg0) == ERROR_MARK || TREE_CODE (arg1) == ERROR_MARK
>|| TREE_TYPE (arg0) == error_mark_node
> --- gcc/testsuite/g++.dg/cpp0x/constexpr-89709.C.jj 2019-03-14
> 11:41:28.270346813 +0100
> +++ gcc/testsuite/g++.dg/cpp0x/constexpr-89709.C 2019-03-14
> 11:40:59.161816938 +0100
> @@ -0,0 +1,18 @@
> +// PR c++/89709
> +// { dg-do compile { target c++11 } }
> +// { dg-options "-O" }
> +
> +struct A { int i; };
> +A a;
> +
> +constexpr int *
> +foo ()
> +{
> + return &a.i;
> +}
> +
> +bool
> +bar ()
> +{
> + return foo () == &a.i;
> +}
>
>
> Jakub
>
--
Richard Biener
SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Graham Norton, HRB
21284 (AG Nuernberg)