re PR c++/49554 ([C++0x] lambda capture causes "cannot call member function ... without object")
PR c++/49554 * semantics.c (lambda_proxy_type): New. (build_capture_proxy): Use it. * cp-tree.h (DECLTYPE_FOR_LAMBDA_PROXY): New. * pt.c (tsubst) [DECLTYPE_TYPE]: Use them. From-SVN: r175657
This commit is contained in:
parent
de95483d1e
commit
40d55020a3
@ -1,5 +1,11 @@
|
||||
2011-06-29 Jason Merrill <jason@redhat.com>
|
||||
|
||||
PR c++/49554
|
||||
* semantics.c (lambda_proxy_type): New.
|
||||
(build_capture_proxy): Use it.
|
||||
* cp-tree.h (DECLTYPE_FOR_LAMBDA_PROXY): New.
|
||||
* pt.c (tsubst) [DECLTYPE_TYPE]: Use them.
|
||||
|
||||
PR c++/45923
|
||||
* class.c (explain_non_literal_class): New.
|
||||
(finalize_literal_type_property): Call it.
|
||||
|
@ -3418,11 +3418,13 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter)
|
||||
|
||||
/* These flags indicate that we want different semantics from normal
|
||||
decltype: lambda capture just drops references, lambda return also does
|
||||
type decay. */
|
||||
type decay, lambda proxies look through implicit dereference. */
|
||||
#define DECLTYPE_FOR_LAMBDA_CAPTURE(NODE) \
|
||||
TREE_LANG_FLAG_0 (DECLTYPE_TYPE_CHECK (NODE))
|
||||
#define DECLTYPE_FOR_LAMBDA_RETURN(NODE) \
|
||||
TREE_LANG_FLAG_1 (DECLTYPE_TYPE_CHECK (NODE))
|
||||
#define DECLTYPE_FOR_LAMBDA_PROXY(NODE) \
|
||||
TREE_LANG_FLAG_2 (DECLTYPE_TYPE_CHECK (NODE))
|
||||
|
||||
/* Nonzero for VAR_DECL and FUNCTION_DECL node means that `extern' was
|
||||
specified in its declaration. This can also be set for an
|
||||
@ -5455,6 +5457,7 @@ extern tree build_lambda_object (tree);
|
||||
extern tree begin_lambda_type (tree);
|
||||
extern tree lambda_capture_field_type (tree);
|
||||
extern tree lambda_return_type (tree);
|
||||
extern tree lambda_proxy_type (tree);
|
||||
extern tree lambda_function (tree);
|
||||
extern void apply_lambda_return_type (tree, tree);
|
||||
extern tree add_capture (tree, tree, tree, bool, bool);
|
||||
|
@ -11108,6 +11108,8 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
|
||||
type = lambda_capture_field_type (type);
|
||||
else if (DECLTYPE_FOR_LAMBDA_RETURN (t))
|
||||
type = lambda_return_type (type);
|
||||
else if (DECLTYPE_FOR_LAMBDA_PROXY (t))
|
||||
type = lambda_proxy_type (type);
|
||||
else
|
||||
type = finish_decltype_type
|
||||
(type, DECLTYPE_TYPE_ID_EXPR_OR_MEMBER_ACCESS_P (t), complain);
|
||||
|
@ -8489,6 +8489,27 @@ insert_pending_capture_proxies (void)
|
||||
LAMBDA_EXPR_PENDING_PROXIES (lam) = NULL;
|
||||
}
|
||||
|
||||
/* Given REF, a COMPONENT_REF designating a field in the lambda closure,
|
||||
return the type we want the proxy to have: the type of the field itself,
|
||||
with added const-qualification if the lambda isn't mutable and the
|
||||
capture is by value. */
|
||||
|
||||
tree
|
||||
lambda_proxy_type (tree ref)
|
||||
{
|
||||
tree type;
|
||||
if (REFERENCE_REF_P (ref))
|
||||
ref = TREE_OPERAND (ref, 0);
|
||||
type = TREE_TYPE (ref);
|
||||
if (!dependent_type_p (type))
|
||||
return type;
|
||||
type = cxx_make_type (DECLTYPE_TYPE);
|
||||
DECLTYPE_TYPE_EXPR (type) = ref;
|
||||
DECLTYPE_FOR_LAMBDA_PROXY (type) = true;
|
||||
SET_TYPE_STRUCTURAL_EQUALITY (type);
|
||||
return type;
|
||||
}
|
||||
|
||||
/* MEMBER is a capture field in a lambda closure class. Now that we're
|
||||
inside the operator(), build a placeholder var for future lookups and
|
||||
debugging. */
|
||||
@ -8496,7 +8517,7 @@ insert_pending_capture_proxies (void)
|
||||
tree
|
||||
build_capture_proxy (tree member)
|
||||
{
|
||||
tree var, object, fn, closure, name, lam;
|
||||
tree var, object, fn, closure, name, lam, type;
|
||||
|
||||
closure = DECL_CONTEXT (member);
|
||||
fn = lambda_function (closure);
|
||||
@ -8511,7 +8532,8 @@ build_capture_proxy (tree member)
|
||||
/* Remove the __ inserted by add_capture. */
|
||||
name = get_identifier (IDENTIFIER_POINTER (DECL_NAME (member)) + 2);
|
||||
|
||||
var = build_decl (input_location, VAR_DECL, name, TREE_TYPE (object));
|
||||
type = lambda_proxy_type (object);
|
||||
var = build_decl (input_location, VAR_DECL, name, type);
|
||||
SET_DECL_VALUE_EXPR (var, object);
|
||||
DECL_HAS_VALUE_EXPR_P (var) = 1;
|
||||
DECL_ARTIFICIAL (var) = 1;
|
||||
|
@ -1,5 +1,7 @@
|
||||
2011-06-29 Jason Merrill <jason@redhat.com>
|
||||
|
||||
* g++.dg/cpp0x/lambda/lambda-template3.C: New.
|
||||
|
||||
PR c++/45923
|
||||
* g++.dg/cpp0x/constexpr-diag3.C: New.
|
||||
* g++.dg/cpp0x/constexpr-diag1.C: Adjust error message.
|
||||
|
33
gcc/testsuite/g++.dg/cpp0x/lambda/lambda-template3.C
Normal file
33
gcc/testsuite/g++.dg/cpp0x/lambda/lambda-template3.C
Normal file
@ -0,0 +1,33 @@
|
||||
// PR c++/49554
|
||||
// { dg-options -std=c++0x }
|
||||
|
||||
template<typename T>
|
||||
struct base
|
||||
{
|
||||
struct iterator { };
|
||||
|
||||
iterator begin();
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class flist : public base<T>
|
||||
{
|
||||
typedef base<T> Base;
|
||||
|
||||
typedef typename Base::iterator Base_iterator;
|
||||
public:
|
||||
|
||||
void
|
||||
resize()
|
||||
{
|
||||
Base_iterator b = Base::begin();
|
||||
|
||||
[b](int i) { return i; };
|
||||
}
|
||||
};
|
||||
|
||||
void test01()
|
||||
{
|
||||
flist<int> fl;
|
||||
fl.resize();
|
||||
}
|
Loading…
Reference in New Issue
Block a user