re PR c++/56447 ([C++11] Lambda in template has conversion op it shouldn't have)

PR c++/56447
	PR c++/55532
	* pt.c (instantiate_class_template_1): Instantiate lambda capture
	list here.
	(tsubst_copy_and_build): Not here.

From-SVN: r196729
This commit is contained in:
Jason Merrill 2013-03-16 22:35:18 -04:00 committed by Jason Merrill
parent 5275b2c7d7
commit e2adfdad84
4 changed files with 59 additions and 7 deletions

View File

@ -1,5 +1,11 @@
2013-03-16 Jason Merrill <jason@redhat.com>
PR c++/56447
PR c++/55532
* pt.c (instantiate_class_template_1): Instantiate lambda capture
list here.
(tsubst_copy_and_build): Not here.
PR c++/55017
* method.c (walk_field_subobs): Disallow copy of rvalue ref.

View File

@ -8991,12 +8991,26 @@ instantiate_class_template_1 (tree type)
}
}
if (CLASSTYPE_LAMBDA_EXPR (type))
if (tree expr = CLASSTYPE_LAMBDA_EXPR (type))
{
tree decl = lambda_function (type);
if (decl)
{
instantiate_decl (decl, false, false);
/* We need to instantiate the capture list from the template
after we've instantiated the closure members, but before we
consider adding the conversion op. Also keep any captures
that may have been added during instantiation of the op(). */
tree tmpl_expr = CLASSTYPE_LAMBDA_EXPR (pattern);
tree tmpl_cap
= tsubst_copy_and_build (LAMBDA_EXPR_CAPTURE_LIST (tmpl_expr),
args, tf_warning_or_error, NULL_TREE,
false, false);
LAMBDA_EXPR_CAPTURE_LIST (expr)
= chainon (tmpl_cap, nreverse (LAMBDA_EXPR_CAPTURE_LIST (expr)));
maybe_add_lambda_conv_op (type);
}
else
@ -14470,12 +14484,6 @@ tsubst_copy_and_build (tree t,
declaration of the op() for later calls to lambda_function. */
complete_type (type);
/* The capture list refers to closure members, so this needs to
wait until after we finish instantiating the type. Also keep
any captures that may have been added during instantiation. */
LAMBDA_EXPR_CAPTURE_LIST (r)
= chainon (RECUR (LAMBDA_EXPR_CAPTURE_LIST (t)),
LAMBDA_EXPR_CAPTURE_LIST (r));
LAMBDA_EXPR_THIS_CAPTURE (r) = NULL_TREE;
RETURN (build_lambda_object (r));

View File

@ -0,0 +1,15 @@
// PR c++/56447
// { dg-do compile { target c++11 } }
template <class T>
void f()
{
int i;
// This lambda should not have a conversion op, since it captures i
int (*p)() = [=]{ return i; }; // { dg-error "cannot convert" }
}
int main()
{
f<int>();
}

View File

@ -0,0 +1,23 @@
// PR c++/55532
// { dg-do compile { target c++11 } }
struct Foo {
void doit() {
}
};
template<typename T>
void oops(Foo &foo, const T &) {
auto fun = [&] () mutable {
foo.doit();
};
auto fun2 = [=]() {
fun(); // { dg-error "" }
};
fun2();
}
int main() {
Foo foo;
oops(foo, 1);
}