]> git.ipfire.org Git - thirdparty/gcc.git/commit
c++: Fix constexpr evaluation of pre-increment when !lval [PR99287]
authorPatrick Palka <ppalka@redhat.com>
Sat, 6 Mar 2021 22:09:07 +0000 (17:09 -0500)
committerPatrick Palka <ppalka@redhat.com>
Sat, 6 Mar 2021 22:09:07 +0000 (17:09 -0500)
commitd1bba463bd0d5692b7fa58ee37a61a55b2517456
treebe0148634d2c34eef8a04b6d29afa943ea11844e
parent0cc54a68e309df89fb47bc1fa6c23662c45eeacc
c++: Fix constexpr evaluation of pre-increment when !lval [PR99287]

Here, during cxx_eval_increment_expression (with lval=false) of
++__first where __first is &"mystr"[0], we correctly update __first
to &"mystr"[1] but we end up returning &"mystr"[0] + 1 instead of
&"mystr"[1].  This unreduced return value inhibits other pointer
arithmetic folding during later constexpr evaluation, which ultimately
causes the constexpr evaluation to fail.

It turns out the simplification of &"mystr"[0] + 1 to &"mystr"[1]
is performed by cxx_fold_pointer_plus_expression, not by fold_build2.
So we perform this simplification during constexpr evaluation of
the temporary MODIFY_EXPR (during which we assign to __first the
simplified value), but then we return 'mod' which has only been folded
via fold_build2 and hasn't gone through cxx_fold_pointer_plus_expression.

This patch fixes this by updating 'mod' with the result of the
MODIFY_EXPR evaluation appropriately, so that it captures any additional
folding of the expression when !lval.  We now need to be wary of this
evaluation failing and returning e.g. the MODIFY_EXPR or NULL_TREE; it
seems checking *non_constant_p should cover our bases here and is
generally prudent.

gcc/cp/ChangeLog:

PR c++/99287
* constexpr.c (cxx_eval_increment_expression): Pass lval when
evaluating the MODIFY_EXPR, and update 'mod' with the result of
this evaluation.  Check *non_constant_p afterwards.  For prefix
ops, just return 'mod'.

gcc/testsuite/ChangeLog:

PR c++/99287
* g++.dg/cpp2a/constexpr-99287.C: New test.

Co-authored-by: Jakub Jelinek <jakub@redhat.com>
gcc/cp/constexpr.c
gcc/testsuite/g++.dg/cpp2a/constexpr-99287.C [new file with mode: 0644]