From 1ee2604721c1e6b926d6c28aa4b4d42c6e85332f Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Fri, 17 Feb 2017 11:50:16 -0500 Subject: [PATCH] PR c++/79533 - C++17 ICE with temporary cast to reference * call.c (build_over_call): Conversion to a reference prevents copy elision. From-SVN: r245538 --- gcc/cp/ChangeLog | 6 ++++++ gcc/cp/call.c | 9 ++++++++- gcc/testsuite/g++.dg/init/elide6.C | 11 +++++++++++ 3 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/g++.dg/init/elide6.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 11ef320..a1e4948 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2017-02-17 Jason Merrill + + PR c++/79533 - C++17 ICE with temporary cast to reference + * call.c (build_over_call): Conversion to a reference prevents copy + elision. + 2017-02-16 Jakub Jelinek Jason Merrill diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 154509b..4ef444b 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -7955,7 +7955,14 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain) /* Pull out the real argument, disregarding const-correctness. */ targ = arg; - while (CONVERT_EXPR_P (targ) + /* Strip the reference binding for the constructor parameter. */ + if (CONVERT_EXPR_P (targ) + && TREE_CODE (TREE_TYPE (targ)) == REFERENCE_TYPE) + targ = TREE_OPERAND (targ, 0); + /* But don't strip any other reference bindings; binding a temporary to a + reference prevents copy elision. */ + while ((CONVERT_EXPR_P (targ) + && TREE_CODE (TREE_TYPE (targ)) != REFERENCE_TYPE) || TREE_CODE (targ) == NON_LVALUE_EXPR) targ = TREE_OPERAND (targ, 0); if (TREE_CODE (targ) == ADDR_EXPR) diff --git a/gcc/testsuite/g++.dg/init/elide6.C b/gcc/testsuite/g++.dg/init/elide6.C new file mode 100644 index 0000000..d40bd9d --- /dev/null +++ b/gcc/testsuite/g++.dg/init/elide6.C @@ -0,0 +1,11 @@ +// PR c++/79533 + +struct S { + S(); + S(const S&); +}; +S f(); +S s(static_cast(f())); + +// The static_cast prevents copy elision. +// { dg-final { scan-assembler "_ZN1SC1ERKS_" } } -- 2.7.4