From 6aa80414a003b2cd9af254e4701838072a1f17dd Mon Sep 17 00:00:00 2001 From: Nathan Sidwell Date: Mon, 20 Nov 2017 14:39:00 +0000 Subject: [PATCH] [PR c++/82878] pass-by-invisiref in lambda https://gcc.gnu.org/ml/gcc-patches/2017-11/msg01115.html PR c++/82878 PR c++/78495 * call.c (build_call_a): Don't set CALL_FROM_THUNK_P for inherited ctor. * cp-gimplify.c (cp_genericize_r): Restore THUNK dereference inhibibition check removed in previous c++/78495 change. PR c++/82878 * g++.dg/cpp0x/pr82878.C: New. * g++.dg/cpp1z/inh-ctor38.C: Check moves too. From-SVN: r254958 --- gcc/cp/ChangeLog | 9 +++++++++ gcc/cp/call.c | 10 +--------- gcc/cp/cp-gimplify.c | 8 ++++++++ gcc/cp/lambda.c | 1 - gcc/testsuite/ChangeLog | 6 ++++++ .../g++.dg/cpp0x/lambda/lambda-switch.C | 2 +- gcc/testsuite/g++.dg/cpp0x/pr82878.C | 20 +++++++++++++++++++ gcc/testsuite/g++.dg/cpp1z/inh-ctor38.C | 16 ++++++++++++--- 8 files changed, 58 insertions(+), 14 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/pr82878.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 6f4d30e1dfb..e1e9d7238a6 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,12 @@ +2017-11-20 Nathan Sidwell + + PR c++/82878 + PR c++/78495 + * call.c (build_call_a): Don't set CALL_FROM_THUNK_P for inherited + ctor. + * cp-gimplify.c (cp_genericize_r): Restore THUNK dereference + inhibibition check removed in previous c++/78495 change. + 2017-11-20 Jakub Jelinek PR c++/82781 diff --git a/gcc/cp/call.c b/gcc/cp/call.c index e09cf97920b..d242b07a06b 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -376,18 +376,10 @@ build_call_a (tree function, int n, tree *argarray) TREE_HAS_CONSTRUCTOR (function) = (decl && DECL_CONSTRUCTOR_P (decl)); - if (current_function_decl && decl - && flag_new_inheriting_ctors - && DECL_INHERITED_CTOR (current_function_decl) - && (DECL_INHERITED_CTOR (current_function_decl) - == DECL_CLONED_FUNCTION (decl))) - /* Pass arguments directly to the inherited constructor. */ - CALL_FROM_THUNK_P (function) = true; - /* Don't pass empty class objects by value. This is useful for tags in STL, which are used to control overload resolution. We don't need to handle other cases of copying empty classes. */ - else if (! decl || ! DECL_BUILT_IN (decl)) + if (! decl || ! DECL_BUILT_IN (decl)) for (i = 0; i < n; i++) { tree arg = CALL_EXPR_ARG (function, i); diff --git a/gcc/cp/cp-gimplify.c b/gcc/cp/cp-gimplify.c index 8849f9d3735..201a5950591 100644 --- a/gcc/cp/cp-gimplify.c +++ b/gcc/cp/cp-gimplify.c @@ -1078,6 +1078,14 @@ cp_genericize_r (tree *stmt_p, int *walk_subtrees, void *data) && omp_var_to_track (stmt)) omp_cxx_notice_variable (wtd->omp_ctx, stmt); + /* Don't dereference parms in a thunk, pass the references through. */ + if ((TREE_CODE (stmt) == CALL_EXPR && CALL_FROM_THUNK_P (stmt)) + || (TREE_CODE (stmt) == AGGR_INIT_EXPR && AGGR_INIT_FROM_THUNK_P (stmt))) + { + *walk_subtrees = 0; + return NULL; + } + /* Dereference invisible reference parms. */ if (wtd->handle_invisiref_parm_p && is_invisiref_parm (stmt)) { diff --git a/gcc/cp/lambda.c b/gcc/cp/lambda.c index 4480c67dc5f..76a839ce730 100644 --- a/gcc/cp/lambda.c +++ b/gcc/cp/lambda.c @@ -1103,7 +1103,6 @@ maybe_add_lambda_conv_op (tree type) } } - if (generic_lambda_p) { if (decltype_call) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 85e4c71e8b5..ba7426a38a4 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2017-11-20 Nathan Sidwell + + PR c++/82878 + * g++.dg/cpp0x/pr82878.C: New. + * g++.dg/cpp1z/inh-ctor38.C: Check moves too. + 2017-11-20 Bin Cheng * gcc.dg/tree-ssa/predcom-dse-12.c: New test. diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-switch.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-switch.C index 328410e29aa..d05c9760709 100644 --- a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-switch.C +++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-switch.C @@ -20,7 +20,7 @@ main () { case 3: // { dg-error "case" } break; // { dg-error "break" } - }; + }; // { dg-warning "statement will never be executed" } } } } diff --git a/gcc/testsuite/g++.dg/cpp0x/pr82878.C b/gcc/testsuite/g++.dg/cpp0x/pr82878.C new file mode 100644 index 00000000000..c75e93b56c3 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/pr82878.C @@ -0,0 +1,20 @@ +// { dg-do compile { target c++11 } } +// { dg-additional-options "-O" } +// pr 82878 erroneously unwrapped a reference parm in the lambda::_FUN +// thunk. + +struct A { + ~A(); + operator int (); +}; + +void baz (); + +void +bar (A b) +{ + void (*lam) (A) = [](A) { baz (); }; + + if (auto c = b) + lam (c); +} diff --git a/gcc/testsuite/g++.dg/cpp1z/inh-ctor38.C b/gcc/testsuite/g++.dg/cpp1z/inh-ctor38.C index fbee8ca5c9e..356c36f5ff6 100644 --- a/gcc/testsuite/g++.dg/cpp1z/inh-ctor38.C +++ b/gcc/testsuite/g++.dg/cpp1z/inh-ctor38.C @@ -1,17 +1,19 @@ // { dg-do run { target c++11 } } // PR78495 failed to propagate pass-by-value struct to base ctor. +static int moves = 0; + struct Ptr { void *ptr = 0; Ptr() {} Ptr(Ptr const&) = delete; - Ptr(Ptr&& other) : ptr (other.ptr) {} + Ptr(Ptr&& other) : ptr (other.ptr) {moves++;} }; struct Base { Ptr val; - Base(Ptr val_) : val(static_cast(val_)) {} + Base(Ptr val_); }; struct Derived: Base { @@ -27,5 +29,13 @@ void *Foo () { } int main () { - return Foo () != 0; + if (Foo ()) + return 1; + + if (moves != 2) + return 2; + + return 0; } + +Base::Base(Ptr val_) : val(static_cast(val_)) {} -- 2.30.2