aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2011-06-29 13:15:06 -0400
committerJason Merrill <jason@gcc.gnu.org>2011-06-29 13:15:06 -0400
commit40d55020a382cc1836911b9702f6880b49c1d955 (patch)
tree24938062efd7fb502da82065526a9b3c36fe7213 /gcc/cp
parentde95483d1e787c73bf1c84e47254bdab4f839762 (diff)
downloadgcc-40d55020a382cc1836911b9702f6880b49c1d955.zip
gcc-40d55020a382cc1836911b9702f6880b49c1d955.tar.gz
gcc-40d55020a382cc1836911b9702f6880b49c1d955.tar.bz2
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
Diffstat (limited to 'gcc/cp')
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/cp-tree.h5
-rw-r--r--gcc/cp/pt.c2
-rw-r--r--gcc/cp/semantics.c26
4 files changed, 36 insertions, 3 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index db0478a..083d545 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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.
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 7244cc8..55c88e3 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -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);
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index b3dd85f..d1d8336 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -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);
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 4581729..fb984d4 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -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;