Commit 6aa80414 by Nathan Sidwell Committed by Nathan Sidwell

[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
parent 7b7b60c8
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)
......
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" }
}
}
}
......
// { 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);
}
// { 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_)) {}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment