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.
/* 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
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);
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);
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. */
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);
/* 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;
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.
--- /dev/null
+// 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();
+}