From: Nathan Sidwell Date: Mon, 20 Nov 2017 14:39:00 +0000 (+0000) Subject: [PR c++/82878] pass-by-invisiref in lambda X-Git-Tag: basepoints/gcc-9~3200 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6aa80414a003b2cd9af254e4701838072a1f17dd;p=thirdparty%2Fgcc.git [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 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 6f4d30e1dfbe..e1e9d7238a68 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 e09cf97920b5..d242b07a06bc 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 8849f9d3735e..201a59505916 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 4480c67dc5f6..76a839ce7304 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 85e4c71e8b54..ba7426a38a44 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 328410e29aa1..d05c9760709a 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 000000000000..c75e93b56c30 --- /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 fbee8ca5c9ed..356c36f5ff61 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_)) {}