Commit b3eae0dd by Jason Merrill Committed by Jason Merrill

Fix lambdas in template default argument of inherited ctor.

	* method.c (synthesized_method_base_walk): Replace an inherited
	template with its specialization.
	(synthesized_method_walk): Make inheriting_ctor a pointer.
	(maybe_explain_implicit_delete, explain_implicit_non_constexpr)
	(deduce_inheriting_ctor, implicitly_declare_fn): Adjust.

From-SVN: r251426
parent 4cc20315
2017-08-29 Jason Merrill <jason@redhat.com> 2017-08-29 Jason Merrill <jason@redhat.com>
Fix lambdas in template default argument of inherited ctor.
* method.c (synthesized_method_base_walk): Replace an inherited
template with its specialization.
(synthesized_method_walk): Make inheriting_ctor a pointer.
(maybe_explain_implicit_delete, explain_implicit_non_constexpr)
(deduce_inheriting_ctor, implicitly_declare_fn): Adjust.
* pt.c (build_deduction_guide): Set DECL_ABSTRACT_ORIGIN on the * pt.c (build_deduction_guide): Set DECL_ABSTRACT_ORIGIN on the
template, not the function. template, not the function.
(template_guide_p): Adjust. (template_guide_p): Adjust.
......
...@@ -1458,7 +1458,7 @@ static tree ...@@ -1458,7 +1458,7 @@ static tree
synthesized_method_base_walk (tree binfo, tree base_binfo, synthesized_method_base_walk (tree binfo, tree base_binfo,
int quals, bool copy_arg_p, int quals, bool copy_arg_p,
bool move_p, bool ctor_p, bool move_p, bool ctor_p,
tree inheriting_ctor, tree inherited_parms, tree *inheriting_ctor, tree inherited_parms,
tree fnname, int flags, bool diag, tree fnname, int flags, bool diag,
tree *spec_p, bool *trivial_p, tree *spec_p, bool *trivial_p,
bool *deleted_p, bool *constexpr_p) bool *deleted_p, bool *constexpr_p)
...@@ -1469,8 +1469,9 @@ synthesized_method_base_walk (tree binfo, tree base_binfo, ...@@ -1469,8 +1469,9 @@ synthesized_method_base_walk (tree binfo, tree base_binfo,
if (copy_arg_p) if (copy_arg_p)
argtype = build_stub_type (BINFO_TYPE (base_binfo), quals, move_p); argtype = build_stub_type (BINFO_TYPE (base_binfo), quals, move_p);
else if ((inherited_binfo else if (inheriting_ctor
= binfo_inherited_from (binfo, base_binfo, inheriting_ctor))) && (inherited_binfo
= binfo_inherited_from (binfo, base_binfo, *inheriting_ctor)))
{ {
argtype = inherited_parms; argtype = inherited_parms;
/* Don't check access on the inherited constructor. */ /* Don't check access on the inherited constructor. */
...@@ -1492,6 +1493,12 @@ synthesized_method_base_walk (tree binfo, tree base_binfo, ...@@ -1492,6 +1493,12 @@ synthesized_method_base_walk (tree binfo, tree base_binfo,
if (defer != dk_no_deferred) if (defer != dk_no_deferred)
pop_deferring_access_checks (); pop_deferring_access_checks ();
/* Replace an inherited template with the appropriate specialization. */
if (inherited_binfo && rval
&& DECL_P (*inheriting_ctor) && DECL_P (rval)
&& DECL_CONTEXT (*inheriting_ctor) == DECL_CONTEXT (rval))
*inheriting_ctor = DECL_CLONED_FUNCTION (rval);
process_subob_fn (rval, spec_p, trivial_p, deleted_p, process_subob_fn (rval, spec_p, trivial_p, deleted_p,
constexpr_p, diag, BINFO_TYPE (base_binfo)); constexpr_p, diag, BINFO_TYPE (base_binfo));
if (ctor_p && if (ctor_p &&
...@@ -1526,7 +1533,7 @@ static void ...@@ -1526,7 +1533,7 @@ static void
synthesized_method_walk (tree ctype, special_function_kind sfk, bool const_p, synthesized_method_walk (tree ctype, special_function_kind sfk, bool const_p,
tree *spec_p, bool *trivial_p, bool *deleted_p, tree *spec_p, bool *trivial_p, bool *deleted_p,
bool *constexpr_p, bool diag, bool *constexpr_p, bool diag,
tree inheriting_ctor, tree inherited_parms) tree *inheriting_ctor, tree inherited_parms)
{ {
tree binfo, base_binfo, fnname; tree binfo, base_binfo, fnname;
int i; int i;
...@@ -1581,7 +1588,7 @@ synthesized_method_walk (tree ctype, special_function_kind sfk, bool const_p, ...@@ -1581,7 +1588,7 @@ synthesized_method_walk (tree ctype, special_function_kind sfk, bool const_p,
} }
gcc_assert ((sfk == sfk_inheriting_constructor) gcc_assert ((sfk == sfk_inheriting_constructor)
== (inheriting_ctor != NULL_TREE)); == (inheriting_ctor && *inheriting_ctor != NULL_TREE));
/* If that user-written default constructor would satisfy the /* If that user-written default constructor would satisfy the
requirements of a constexpr constructor (7.1.5), the requirements of a constexpr constructor (7.1.5), the
...@@ -1656,7 +1663,7 @@ synthesized_method_walk (tree ctype, special_function_kind sfk, bool const_p, ...@@ -1656,7 +1663,7 @@ synthesized_method_walk (tree ctype, special_function_kind sfk, bool const_p,
tree scope = push_scope (ctype); tree scope = push_scope (ctype);
int flags = LOOKUP_NORMAL | LOOKUP_SPECULATIVE; int flags = LOOKUP_NORMAL | LOOKUP_SPECULATIVE;
if (!inheriting_ctor) if (sfk != sfk_inheriting_constructor)
flags |= LOOKUP_DEFAULTED; flags |= LOOKUP_DEFAULTED;
tsubst_flags_t complain = diag ? tf_warning_or_error : tf_none; tsubst_flags_t complain = diag ? tf_warning_or_error : tf_none;
...@@ -1770,9 +1777,9 @@ get_defaulted_eh_spec (tree decl, tsubst_flags_t complain) ...@@ -1770,9 +1777,9 @@ get_defaulted_eh_spec (tree decl, tsubst_flags_t complain)
bool const_p = CP_TYPE_CONST_P (non_reference (parm_type)); bool const_p = CP_TYPE_CONST_P (non_reference (parm_type));
tree spec = empty_except_spec; tree spec = empty_except_spec;
bool diag = !DECL_DELETED_FN (decl) && (complain & tf_error); bool diag = !DECL_DELETED_FN (decl) && (complain & tf_error);
tree inh = DECL_INHERITED_CTOR (decl);
synthesized_method_walk (ctype, sfk, const_p, &spec, NULL, NULL, synthesized_method_walk (ctype, sfk, const_p, &spec, NULL, NULL,
NULL, diag, DECL_INHERITED_CTOR (decl), NULL, diag, &inh, parms);
parms);
return spec; return spec;
} }
...@@ -1847,10 +1854,11 @@ maybe_explain_implicit_delete (tree decl) ...@@ -1847,10 +1854,11 @@ maybe_explain_implicit_delete (tree decl)
tree raises = NULL_TREE; tree raises = NULL_TREE;
bool deleted_p = false; bool deleted_p = false;
tree scope = push_scope (ctype); tree scope = push_scope (ctype);
tree inh = DECL_INHERITED_CTOR (decl);
synthesized_method_walk (ctype, sfk, const_p, synthesized_method_walk (ctype, sfk, const_p,
&raises, NULL, &deleted_p, NULL, false, &raises, NULL, &deleted_p, NULL, false,
DECL_INHERITED_CTOR (decl), parms); &inh, parms);
if (deleted_p) if (deleted_p)
{ {
inform (DECL_SOURCE_LOCATION (decl), inform (DECL_SOURCE_LOCATION (decl),
...@@ -1858,7 +1866,7 @@ maybe_explain_implicit_delete (tree decl) ...@@ -1858,7 +1866,7 @@ maybe_explain_implicit_delete (tree decl)
"definition would be ill-formed:", decl); "definition would be ill-formed:", decl);
synthesized_method_walk (ctype, sfk, const_p, synthesized_method_walk (ctype, sfk, const_p,
NULL, NULL, NULL, NULL, true, NULL, NULL, NULL, NULL, true,
DECL_INHERITED_CTOR (decl), parms); &inh, parms);
} }
else if (!comp_except_specs else if (!comp_except_specs
(TYPE_RAISES_EXCEPTIONS (TREE_TYPE (decl)), (TYPE_RAISES_EXCEPTIONS (TREE_TYPE (decl)),
...@@ -1887,11 +1895,12 @@ explain_implicit_non_constexpr (tree decl) ...@@ -1887,11 +1895,12 @@ explain_implicit_non_constexpr (tree decl)
{ {
tree parm_type = TREE_VALUE (FUNCTION_FIRST_USER_PARMTYPE (decl)); tree parm_type = TREE_VALUE (FUNCTION_FIRST_USER_PARMTYPE (decl));
bool const_p = CP_TYPE_CONST_P (non_reference (parm_type)); bool const_p = CP_TYPE_CONST_P (non_reference (parm_type));
tree inh = DECL_INHERITED_CTOR (decl);
bool dummy; bool dummy;
synthesized_method_walk (DECL_CLASS_CONTEXT (decl), synthesized_method_walk (DECL_CLASS_CONTEXT (decl),
special_function_p (decl), const_p, special_function_p (decl), const_p,
NULL, NULL, NULL, &dummy, true, NULL, NULL, NULL, &dummy, true,
DECL_INHERITED_CTOR (decl), &inh,
FUNCTION_FIRST_USER_PARMTYPE (decl)); FUNCTION_FIRST_USER_PARMTYPE (decl));
} }
...@@ -1906,22 +1915,25 @@ deduce_inheriting_ctor (tree decl) ...@@ -1906,22 +1915,25 @@ deduce_inheriting_ctor (tree decl)
gcc_assert (DECL_INHERITED_CTOR (decl)); gcc_assert (DECL_INHERITED_CTOR (decl));
tree spec; tree spec;
bool trivial, constexpr_, deleted; bool trivial, constexpr_, deleted;
tree inh = DECL_INHERITED_CTOR (decl);
synthesized_method_walk (DECL_CONTEXT (decl), sfk_inheriting_constructor, synthesized_method_walk (DECL_CONTEXT (decl), sfk_inheriting_constructor,
false, &spec, &trivial, &deleted, &constexpr_, false, &spec, &trivial, &deleted, &constexpr_,
/*diag*/false, /*diag*/false,
DECL_INHERITED_CTOR (decl), &inh,
FUNCTION_FIRST_USER_PARMTYPE (decl)); FUNCTION_FIRST_USER_PARMTYPE (decl));
if (TREE_CODE (inherited_ctor_binfo (decl)) != TREE_BINFO) if (TREE_CODE (inherited_ctor_binfo (decl)) != TREE_BINFO)
/* Inherited the same constructor from different base subobjects. */ /* Inherited the same constructor from different base subobjects. */
deleted = true; deleted = true;
DECL_DELETED_FN (decl) = deleted; DECL_DELETED_FN (decl) = deleted;
TREE_TYPE (decl) = build_exception_variant (TREE_TYPE (decl), spec); TREE_TYPE (decl) = build_exception_variant (TREE_TYPE (decl), spec);
SET_DECL_INHERITED_CTOR (decl, inh);
tree clone; tree clone;
FOR_EACH_CLONE (clone, decl) FOR_EACH_CLONE (clone, decl)
{ {
DECL_DELETED_FN (clone) = deleted; DECL_DELETED_FN (clone) = deleted;
TREE_TYPE (clone) = build_exception_variant (TREE_TYPE (clone), spec); TREE_TYPE (clone) = build_exception_variant (TREE_TYPE (clone), spec);
SET_DECL_INHERITED_CTOR (clone, inh);
} }
} }
...@@ -2035,12 +2047,12 @@ implicitly_declare_fn (special_function_kind kind, tree type, ...@@ -2035,12 +2047,12 @@ implicitly_declare_fn (special_function_kind kind, tree type,
raises = noexcept_deferred_spec; raises = noexcept_deferred_spec;
synthesized_method_walk (type, kind, const_p, NULL, &trivial_p, synthesized_method_walk (type, kind, const_p, NULL, &trivial_p,
&deleted_p, &constexpr_p, false, &deleted_p, &constexpr_p, false,
inherited_ctor, inherited_parms); &inherited_ctor, inherited_parms);
} }
else else
synthesized_method_walk (type, kind, const_p, &raises, &trivial_p, synthesized_method_walk (type, kind, const_p, &raises, &trivial_p,
&deleted_p, &constexpr_p, false, &deleted_p, &constexpr_p, false,
inherited_ctor, inherited_parms); &inherited_ctor, inherited_parms);
/* Don't bother marking a deleted constructor as constexpr. */ /* Don't bother marking a deleted constructor as constexpr. */
if (deleted_p) if (deleted_p)
constexpr_p = false; constexpr_p = false;
...@@ -2153,7 +2165,7 @@ implicitly_declare_fn (special_function_kind kind, tree type, ...@@ -2153,7 +2165,7 @@ implicitly_declare_fn (special_function_kind kind, tree type,
input_location = DECL_SOURCE_LOCATION (fn); input_location = DECL_SOURCE_LOCATION (fn);
synthesized_method_walk (type, kind, const_p, synthesized_method_walk (type, kind, const_p,
NULL, NULL, NULL, NULL, true, NULL, NULL, NULL, NULL, true,
NULL_TREE, NULL_TREE); NULL, NULL_TREE);
input_location = loc; input_location = loc;
} }
......
// { dg-do compile { target c++11 } }
// { dg-final { scan-assembler "_ZZN1AIiEC4IiEET_S2_Ed_NKUlvE_clEv" } }
template <class T> struct A
{
template <class U>
A(U, U = []{ return 42; }());
};
struct B: A<int>
{
using A::A;
};
B b(24);
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