re PR c++/64382 (ICE due to use of this
inside a lambda that captures everything by ref inside a member function of a class template)
Fix PR c++/64382 PR c++/64382 * cp/parser.c (parsing_default_capturing_generic_lambda_in_template): New function. * cp/cp-tree.h: Declare it. * cp/semantics.c (finish_id_expression): Resolve names within a default capturing generic lambda defined within a template prior to instantiation to allow for captures to be added to the closure type. PR c++/64382 * g++.dg/cpp1y/pr64382.C: New test. From-SVN: r244962
This commit is contained in:
parent
0fb9ec83c3
commit
bb6a6ee9db
6 changed files with 73 additions and 3 deletions
|
@ -1,3 +1,13 @@
|
|||
2017-01-27 Adam Butcher <adam@jessamine.co.uk>
|
||||
|
||||
PR c++/64382
|
||||
* cp/parser.c (parsing_default_capturing_generic_lambda_in_template):
|
||||
New function.
|
||||
* cp/cp-tree.h: Declare it.
|
||||
* cp/semantics.c (finish_id_expression): Resolve names within a default
|
||||
capturing generic lambda defined within a template prior to
|
||||
instantiation to allow for captures to be added to the closure type.
|
||||
|
||||
2017-01-26 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR c++/68727
|
||||
|
|
|
@ -6118,6 +6118,7 @@ extern bool maybe_clone_body (tree);
|
|||
/* In parser.c */
|
||||
extern tree cp_convert_range_for (tree, tree, tree, tree, unsigned int, bool);
|
||||
extern bool parsing_nsdmi (void);
|
||||
extern bool parsing_default_capturing_generic_lambda_in_template (void);
|
||||
extern void inject_this_parameter (tree, cp_cv_quals);
|
||||
|
||||
/* in pt.c */
|
||||
|
|
|
@ -20454,6 +20454,33 @@ parsing_nsdmi (void)
|
|||
return false;
|
||||
}
|
||||
|
||||
/* Return true iff our current scope is a default capturing generic lambda
|
||||
defined within a template. FIXME: This is part of a workaround (see
|
||||
semantics.c) to handle building lambda closure types correctly in templates
|
||||
which we ultimately want to defer to instantiation time. */
|
||||
|
||||
bool
|
||||
parsing_default_capturing_generic_lambda_in_template (void)
|
||||
{
|
||||
if (!processing_template_decl || !current_class_type)
|
||||
return false;
|
||||
|
||||
tree lam = CLASSTYPE_LAMBDA_EXPR (current_class_type);
|
||||
if (!lam || LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lam) == CPLD_NONE)
|
||||
return false;
|
||||
|
||||
tree callop = lambda_function (lam);
|
||||
if (!callop)
|
||||
return false;
|
||||
|
||||
return (DECL_TEMPLATE_INFO (callop)
|
||||
&& (DECL_TEMPLATE_RESULT (DECL_TI_TEMPLATE (callop)) == callop)
|
||||
&& ((current_nonlambda_class_type ()
|
||||
&& CLASSTYPE_TEMPLATE_INFO (current_nonlambda_class_type ()))
|
||||
|| ((current_nonlambda_function ()
|
||||
&& DECL_TEMPLATE_INFO (current_nonlambda_function ())))));
|
||||
}
|
||||
|
||||
/* Parse a late-specified return type, if any. This is not a separate
|
||||
non-terminal, but part of a function declarator, which looks like
|
||||
|
||||
|
|
|
@ -3563,9 +3563,13 @@ finish_id_expression (tree id_expression,
|
|||
? CP_ID_KIND_UNQUALIFIED_DEPENDENT
|
||||
: CP_ID_KIND_UNQUALIFIED)));
|
||||
|
||||
/* If the name was dependent on a template parameter, we will
|
||||
resolve the name at instantiation time. */
|
||||
if (dependent_p)
|
||||
/* If the name was dependent on a template parameter and we're not in a
|
||||
default capturing generic lambda within a template, we will resolve the
|
||||
name at instantiation time. FIXME: For lambdas, we should defer
|
||||
building the closure type until instantiation time then we won't need
|
||||
the extra test here. */
|
||||
if (dependent_p
|
||||
&& !parsing_default_capturing_generic_lambda_in_template ())
|
||||
{
|
||||
if (DECL_P (decl)
|
||||
&& any_dependent_type_attributes_p (DECL_ATTRIBUTES (decl)))
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
2017-01-27 Adam Butcher <adam@jessamine.co.uk>
|
||||
|
||||
PR c++/64382
|
||||
* g++.dg/cpp1y/pr64382.C: New test.
|
||||
|
||||
2017-01-26 Martin Sebor <msebor@redhat.com>
|
||||
|
||||
PR middle-end/78703
|
||||
|
|
23
gcc/testsuite/g++.dg/cpp1y/pr64382.C
Normal file
23
gcc/testsuite/g++.dg/cpp1y/pr64382.C
Normal file
|
@ -0,0 +1,23 @@
|
|||
// PR c++/64382
|
||||
// { dg-do compile { target c++14 } }
|
||||
|
||||
template<typename T>
|
||||
struct my_queue
|
||||
{
|
||||
void push(T)
|
||||
{
|
||||
}
|
||||
void ice()
|
||||
{
|
||||
auto L = [=](auto &&v) {
|
||||
push(v);
|
||||
};
|
||||
trav(L);
|
||||
}
|
||||
template<typename F>
|
||||
void trav(F &&f)
|
||||
{
|
||||
f(T());
|
||||
}
|
||||
};
|
||||
template struct my_queue<int>;
|
Loading…
Add table
Reference in a new issue