[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:
Nathan Sidwell 2017-11-20 14:39:00 +00:00 committed by Nathan Sidwell
parent 7b7b60c830
commit 6aa80414a0
8 changed files with 58 additions and 14 deletions

View File

@ -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

View File

@ -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);

View File

@ -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))
{

View File

@ -1103,7 +1103,6 @@ maybe_add_lambda_conv_op (tree type)
}
}
if (generic_lambda_p)
{
if (decltype_call)

View File

@ -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.

View File

@ -20,7 +20,7 @@ main ()
{
case 3: // { dg-error "case" }
break; // { dg-error "break" }
};
}; // { dg-warning "statement will never be executed" }
}
}
}

View 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);
}

View File

@ -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_)) {}