diff options
author | Nathan Sidwell <nathan@acm.org> | 2017-11-20 14:39:00 +0000 |
---|---|---|
committer | Nathan Sidwell <nathan@gcc.gnu.org> | 2017-11-20 14:39:00 +0000 |
commit | 6aa80414a003b2cd9af254e4701838072a1f17dd (patch) | |
tree | ba5912c09897e80e79f8a222c41d3dfae9c08ccd /gcc | |
parent | 7b7b60c83047db2e4bde9e7f40ce3f1738694789 (diff) | |
download | gcc-6aa80414a003b2cd9af254e4701838072a1f17dd.zip gcc-6aa80414a003b2cd9af254e4701838072a1f17dd.tar.gz gcc-6aa80414a003b2cd9af254e4701838072a1f17dd.tar.bz2 |
[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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/cp/call.c | 10 | ||||
-rw-r--r-- | gcc/cp/cp-gimplify.c | 8 | ||||
-rw-r--r-- | gcc/cp/lambda.c | 1 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/lambda/lambda-switch.C | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/pr82878.C | 20 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp1z/inh-ctor38.C | 16 |
8 files changed, 58 insertions, 14 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 6f4d30e..e1e9d72 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,12 @@ +2017-11-20 Nathan Sidwell <nathan@acm.org> + + 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 <jakub@redhat.com> PR c++/82781 diff --git a/gcc/cp/call.c b/gcc/cp/call.c index e09cf97..d242b07 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 8849f9d..201a595 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 4480c67..76a839c 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 85e4c71..ba7426a 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2017-11-20 Nathan Sidwell <nathan@acm.org> + + PR c++/82878 + * g++.dg/cpp0x/pr82878.C: New. + * g++.dg/cpp1z/inh-ctor38.C: Check moves too. + 2017-11-20 Bin Cheng <bin.cheng@arm.com> * 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 328410e..d05c976 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 0000000..c75e93b --- /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 fbee8ca..356c36f 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<Ptr&&>(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<Ptr&&>(val_)) {} |