diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index ebb636e5959..70a93bd8df1 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2011-12-08 Jason Merrill + + PR c++/51459 + * pt.c (tsubst_expr) [DECL_EXPR]: Handle capture proxies properly. + * semantics.c (insert_capture_proxy): No longer static. + * cp-tree.h: Declare it. + 2011-12-07 Jakub Jelinek PR c++/51401 diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index dccf485a60f..87cb8b6d04e 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -5593,6 +5593,7 @@ extern void apply_lambda_return_type (tree, tree); extern tree add_capture (tree, tree, tree, bool, bool); extern tree add_default_capture (tree, tree, tree); extern tree build_capture_proxy (tree); +extern void insert_capture_proxy (tree); extern void insert_pending_capture_proxies (void); extern bool is_capture_proxy (tree); extern bool is_normal_capture_proxy (tree); diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 7603c1151e5..296cd545794 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -12810,6 +12810,11 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl, && ANON_AGGR_TYPE_P (TREE_TYPE (decl))) /* Anonymous aggregates are a special case. */ finish_anon_union (decl); + else if (is_capture_proxy (DECL_EXPR_DECL (t))) + { + DECL_CONTEXT (decl) = current_function_decl; + insert_capture_proxy (decl); + } else { int const_init = false; diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 9a1043a1a9b..2dab6a722a6 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -8804,7 +8804,7 @@ is_normal_capture_proxy (tree decl) /* VAR is a capture proxy created by build_capture_proxy; add it to the current function, which is the operator() for the appropriate lambda. */ -static inline void +void insert_capture_proxy (tree var) { cp_binding_level *b; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index ed2428d8c16..5c97305a784 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2011-12-08 Jason Merrill + + PR c++/51459 + * g++.dg/cpp0x/lambda/lambda-template4.C: New. + 2011-12-08 Jakub Jelinek PR tree-optimization/51466 diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-template4.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-template4.C new file mode 100644 index 00000000000..a65727a1d43 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-template4.C @@ -0,0 +1,42 @@ +// PR c++/51459 +// { dg-do run { target c++11 } } + +struct func { + virtual ~func() { } + virtual void operator()() const = 0; + virtual func* clone() const = 0; +}; + +template +struct funcimpl : func { + explicit funcimpl(T t) : t(t) { } + void operator()() const { t(); } + func* clone() const { return new funcimpl(*this); } + T t; +}; + +struct function +{ + func* p; + + template + function(T t) : p(new funcimpl(t)) { } + + ~function() { delete p; } + + function(const function& f) : p(f.p->clone()) { } + + function& operator=(const function& ) = delete; + + void operator()() const { (*p)(); } +}; + +template +function animate(F f) { return [=]{ f(); }; } + +int main() +{ + function linear1 = []{}; + function av(animate(linear1)); + av(); +}