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
This commit is contained in:
Jason Merrill 2011-12-08 17:28:29 -05:00 committed by Jason Merrill
parent 13a3e5b6d8
commit 4eefc795c1
6 changed files with 61 additions and 1 deletions

View File

@ -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

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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();
}