c++: constexpr base-to-derived conversion with offset 0 [PR103879]
authorPatrick Palka <ppalka@redhat.com>
Mon, 10 Jan 2022 19:57:54 +0000 (14:57 -0500)
committerPatrick Palka <ppalka@redhat.com>
Mon, 10 Jan 2022 19:57:54 +0000 (14:57 -0500)
commitab36b554bd90e8db279d13b133369118814f13fb
tree6c4abc9617dec954ecde670d2c7be09e5044953a
parent3e95a974c39e922d19bf7ac1246730c516ae01f2
c++: constexpr base-to-derived conversion with offset 0 [PR103879]

r12-136 made us canonicalize an object/offset pair with negative offset
into one with a nonnegative offset, by iteratively absorbing the
innermost component into the offset and stopping as soon as the offset
becomes nonnegative.

This patch strengthens this transformation by making it keep on absorbing
even if the offset is already 0 as long as the innermost component is at
position 0 (and thus absorbing doesn't change the offset).  This lets us
accept the two constexpr testcases below, which we'd previously reject
essentially because cxx_fold_indirect_ref would be unable to resolve
*(B*)&b.D123 (where D123 is the base A subobject at position 0) to just b.

PR c++/103879

gcc/cp/ChangeLog:

* constexpr.c (cxx_fold_indirect_ref): Split out object/offset
canonicalization step into a local lambda.  Strengthen it to
absorb more components at position 0.  Use it before both calls
to cxx_fold_indirect_ref_1.

gcc/testsuite/ChangeLog:

* g++.dg/cpp1y/constexpr-base2.C: New test.
* g++.dg/cpp1y/constexpr-base2a.C: New test.
gcc/cp/constexpr.c
gcc/testsuite/g++.dg/cpp1y/constexpr-base2.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp1y/constexpr-base2a.C [new file with mode: 0644]