c++: Delegating constructor in constexpr init [PR94772]
authorPatrick Palka <ppalka@redhat.com>
Mon, 27 Apr 2020 21:06:35 +0000 (17:06 -0400)
committerPatrick Palka <ppalka@redhat.com>
Mon, 27 Apr 2020 21:13:33 +0000 (17:13 -0400)
commit64da1b761db248f4f0d2235a6055c025fbbc94eb
treecd386cb1de5cf78623cf6ce55493058e4c22b602
parent067ebf841300127d9616ddde0b37db03cff60347
c++: Delegating constructor in constexpr init [PR94772]

In the first testcase below, the call to the target constructor foo{} from foo's
delegating constructor is encoded as the INIT_EXPR

  *(struct foo *) this = AGGR_INIT_EXPR <4, __ct_comp, D.2140, ...>;

During initialization of the variable 'bar', we prematurely set TREE_READONLY on
bar's CONSTRUCTOR in two places before the outer delegating constructor has
returned: first, at the end of cxx_eval_call_expression after evaluating the RHS
of the above INIT_EXPR, and second, at the end of cxx_eval_store_expression
after having finished evaluating the above INIT_EXPR.  This then prevents the
rest of the outer delegating constructor from mutating 'bar'.

This (hopefully minimally risky) patch makes cxx_eval_call_expression refrain
from setting TREE_READONLY when evaluating the target constructor of a
delegating constructor.  It also makes cxx_eval_store_expression refrain from
setting TREE_READONLY when the object being initialized is "*this', on the basis
that it should be the responsibility of the routine that set 'this' in the first
place to set the object's TREE_READONLY appropriately.

gcc/cp/ChangeLog:

PR c++/94772
* constexpr.c (cxx_eval_call_expression): Don't set new_obj if we're
evaluating the target constructor of a delegating constructor.
(cxx_eval_store_expression): Don't set TREE_READONLY if the LHS of the
INIT_EXPR is '*this'.

gcc/testsuite/ChangeLog:

PR c++/94772
* g++.dg/cpp1y/constexpr-tracking-const23.C: New test.
* g++.dg/cpp1y/constexpr-tracking-const24.C: New test.
* g++.dg/cpp1y/constexpr-tracking-const25.C: New test.
gcc/cp/ChangeLog
gcc/cp/constexpr.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp1y/constexpr-tracking-const23.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp1y/constexpr-tracking-const24.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp1y/constexpr-tracking-const25.C [new file with mode: 0644]