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:
parent
5275b2c7d7
commit
e2adfdad84
|
@ -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.
|
||||
|
||||
|
|
22
gcc/cp/pt.c
22
gcc/cp/pt.c
|
@ -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));
|
||||
|
|
|
@ -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>();
|
||||
}
|
|
@ -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);
|
||||
}
|
Loading…
Reference in New Issue