From: Jason Merrill Date: Thu, 8 Dec 2011 22:28:29 +0000 (-0500) Subject: re PR c++/51459 ('double free or corruption' involving std::function and lambdas) X-Git-Tag: releases/gcc-4.7.0~1678 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=4eefc795c1af34738cbbe5839fc20415f7b20f39;p=thirdparty%2Fgcc.git re PR c++/51459 ('double free or corruption' involving std::function and lambdas) 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. From-SVN: r182141 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index ebb636e59598..70a93bd8df18 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 dccf485a60fe..87cb8b6d04e5 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 7603c1151e55..296cd545794d 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 9a1043a1a9b6..2dab6a722a6e 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 ed2428d8c16d..5c97305a784d 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 000000000000..a65727a1d43b --- /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(); +}