diff options
author | Jason Merrill <jason@redhat.com> | 2017-02-17 11:50:16 -0500 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2017-02-17 11:50:16 -0500 |
commit | 1ee2604721c1e6b926d6c28aa4b4d42c6e85332f (patch) | |
tree | 6d657a16b46af50a9d543888b615aa1a6b0f8cf0 /gcc | |
parent | 8b4aea7364cbb2e82e0e46810c6a99bf001ff25b (diff) | |
download | gcc-1ee2604721c1e6b926d6c28aa4b4d42c6e85332f.zip gcc-1ee2604721c1e6b926d6c28aa4b4d42c6e85332f.tar.gz gcc-1ee2604721c1e6b926d6c28aa4b4d42c6e85332f.tar.bz2 |
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/call.c | 9 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/init/elide6.C | 11 |
3 files changed, 25 insertions, 1 deletions
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 <jason@redhat.com> + + 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 <jakub@redhat.com> Jason Merrill <jason@redhat.com> 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<S const &>(f())); + +// The static_cast prevents copy elision. +// { dg-final { scan-assembler "_ZN1SC1ERKS_" } } |