[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
This commit is contained in:
parent
7b7b60c830
commit
6aa80414a0
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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))
|
||||
{
|
||||
|
@ -1103,7 +1103,6 @@ maybe_add_lambda_conv_op (tree type)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (generic_lambda_p)
|
||||
{
|
||||
if (decltype_call)
|
||||
|
@ -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.
|
||||
|
@ -20,7 +20,7 @@ main ()
|
||||
{
|
||||
case 3: // { dg-error "case" }
|
||||
break; // { dg-error "break" }
|
||||
};
|
||||
}; // { dg-warning "statement will never be executed" }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
20
gcc/testsuite/g++.dg/cpp0x/pr82878.C
Normal file
20
gcc/testsuite/g++.dg/cpp0x/pr82878.C
Normal file
@ -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);
|
||||
}
|
@ -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_)) {}
|
||||
|
Loading…
x
Reference in New Issue
Block a user