From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2122) id 6F6573875DE3; Fri, 17 Nov 2023 00:21:32 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 6F6573875DE3 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1700180492; bh=BJC9OxjVdiC3/PewvNXMwyJdHWRTfS9nC/ztiGiOV6E=; h=From:To:Subject:Date:From; b=TfM12zn/TPtw929fANZZIdzKyJxMnX2wScwPiQ6OvsXnKW9qiZmmwTrRLK1oZbexu ShQHaRNk+VE83/aw+4g5sIhLyk9cnze298oj6kcSzu+OQCY+3R4mr7kLhQx3CqYzcL lxysENcDXkV6/wbOjNybq6DMkwlgD3Cpq25zaJM0= MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="utf-8" From: Jason Merrill To: gcc-cvs@gcc.gnu.org Subject: [gcc r13-8078] c++: fix contracts with NRV X-Act-Checkin: gcc X-Git-Author: Jason Merrill X-Git-Refname: refs/heads/releases/gcc-13 X-Git-Oldrev: e62dd770afde1745c547d05c8163ee5cd639464b X-Git-Newrev: aabc13dc7dfdede61cc51f96d9e9b942aba66baf Message-Id: <20231117002132.6F6573875DE3@sourceware.org> Date: Fri, 17 Nov 2023 00:21:32 +0000 (GMT) List-Id: https://gcc.gnu.org/g:aabc13dc7dfdede61cc51f96d9e9b942aba66baf commit r13-8078-gaabc13dc7dfdede61cc51f96d9e9b942aba66baf Author: Jason Merrill Date: Mon Jun 5 23:58:32 2023 -0400 c++: fix contracts with NRV The NRV implementation was blindly replacing the operand of RETURN_EXPR, clobbering anything that check_return_expr might have added on to the actual initialization, such as checking the postcondition. gcc/cp/ChangeLog: * semantics.cc (finalize_nrv_r): [RETURN_EXPR]: Only replace the INIT_EXPR. gcc/testsuite/ChangeLog: * g++.dg/contracts/contracts-post7.C: New test. Diff: --- gcc/cp/semantics.cc | 12 ++++++++-- gcc/testsuite/g++.dg/contracts/contracts-post7.C | 29 ++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc index e4a8edb1b25..11abff9756f 100644 --- a/gcc/cp/semantics.cc +++ b/gcc/cp/semantics.cc @@ -4925,9 +4925,17 @@ finalize_nrv_r (tree* tp, int* walk_subtrees, void* data) *walk_subtrees = 0; /* Change all returns to just refer to the RESULT_DECL; this is a nop, but differs from using NULL_TREE in that it indicates that we care - about the value of the RESULT_DECL. */ + about the value of the RESULT_DECL. But preserve anything appended + by check_return_expr. */ else if (TREE_CODE (*tp) == RETURN_EXPR) - TREE_OPERAND (*tp, 0) = dp->result; + { + tree *p = &TREE_OPERAND (*tp, 0); + while (TREE_CODE (*p) == COMPOUND_EXPR) + p = &TREE_OPERAND (*p, 0); + gcc_checking_assert (TREE_CODE (*p) == INIT_EXPR + && TREE_OPERAND (*p, 0) == dp->result); + *p = dp->result; + } /* Change all cleanups for the NRV to only run when an exception is thrown. */ else if (TREE_CODE (*tp) == CLEANUP_STMT diff --git a/gcc/testsuite/g++.dg/contracts/contracts-post7.C b/gcc/testsuite/g++.dg/contracts/contracts-post7.C new file mode 100644 index 00000000000..1c33181b5e6 --- /dev/null +++ b/gcc/testsuite/g++.dg/contracts/contracts-post7.C @@ -0,0 +1,29 @@ +// { dg-do run } +// { dg-options "-std=c++2a -fcontracts" } + +#include + +using std::experimental::contract_violation; +void handle_contract_violation(const contract_violation &violation) +{ + __builtin_exit (0); +} + +struct A { + int i; + A(): i(42) {} + A(const A&); +}; + +A f() + [[ post r: r.i == 24 ]] +{ + A a; + return a; +} + +int main() +{ + f(); + return -1; +}