diff options
author | Jason Merrill <jason@redhat.com> | 2011-12-08 17:28:29 -0500 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2011-12-08 17:28:29 -0500 |
commit | 4eefc795c1af34738cbbe5839fc20415f7b20f39 (patch) | |
tree | 66965afdbe726ca6806beb951c83c5821267d17b | |
parent | 13a3e5b6d8c650d9fb74d641dc058e14b44c6f9d (diff) | |
download | gcc-4eefc795c1af34738cbbe5839fc20415f7b20f39.zip gcc-4eefc795c1af34738cbbe5839fc20415f7b20f39.tar.gz gcc-4eefc795c1af34738cbbe5839fc20415f7b20f39.tar.bz2 |
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
-rw-r--r-- | gcc/cp/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 1 | ||||
-rw-r--r-- | gcc/cp/pt.c | 5 | ||||
-rw-r--r-- | gcc/cp/semantics.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/lambda/lambda-template4.C | 42 |
6 files changed, 61 insertions, 1 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index ebb636e..70a93bd 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2011-12-08 Jason Merrill <jason@redhat.com> + + 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 <jakub@redhat.com> PR c++/51401 diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index dccf485..87cb8b6 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 7603c11..296cd54 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 9a1043a..2dab6a7 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 ed2428d..5c97305 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2011-12-08 Jason Merrill <jason@redhat.com> + + PR c++/51459 + * g++.dg/cpp0x/lambda/lambda-template4.C: New. + 2011-12-08 Jakub Jelinek <jakub@redhat.com> 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 0000000..a65727a --- /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<typename T> +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<typename T> + function(T t) : p(new funcimpl<T>(t)) { } + + ~function() { delete p; } + + function(const function& f) : p(f.p->clone()) { } + + function& operator=(const function& ) = delete; + + void operator()() const { (*p)(); } +}; + +template <typename F> +function animate(F f) { return [=]{ f(); }; } + +int main() +{ + function linear1 = []{}; + function av(animate(linear1)); + av(); +} |