aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/lambda.c
diff options
context:
space:
mode:
authorNathan Sidwell <nathan@acm.org>2017-01-17 18:22:34 +0000
committerNathan Sidwell <nathan@gcc.gnu.org>2017-01-17 18:22:34 +0000
commit8ddfdbc265cfe0da5b727559d3736876d0198afb (patch)
tree127551e9b5d51e1763e5a76af78e43a959b28a43 /gcc/cp/lambda.c
parentf46fe37e86aa04522258dad374d0c7bf9c443ed3 (diff)
downloadgcc-8ddfdbc265cfe0da5b727559d3736876d0198afb.zip
gcc-8ddfdbc265cfe0da5b727559d3736876d0198afb.tar.gz
gcc-8ddfdbc265cfe0da5b727559d3736876d0198afb.tar.bz2
re PR c++/61636 (generic lambda: segfault / "cannot call member function without object")
PR c++/61636 * cp-tree.h (maybe_generic_this_capture): Declare. * lambda.c (resolvable_dummy_lambda): New, broken out of ... (maybe_resolve_dummy): ... here. Call it. (maybe_generic_this_capture): New. * parser.c (cp_parser_postfix_expression): Speculatively capture this in generic lambda in unresolved member function call. * pt.c (tsubst_copy_and_build): Force hard error from failed member function lookup in generic lambda. PR c++/61636 * g++.dg/cpp1y/pr61636-1.C: New. * g++.dg/cpp1y/pr61636-2.C: New. * g++.dg/cpp1y/pr61636-3.C: New. From-SVN: r244544
Diffstat (limited to 'gcc/cp/lambda.c')
-rw-r--r--gcc/cp/lambda.c61
1 files changed, 48 insertions, 13 deletions
diff --git a/gcc/cp/lambda.c b/gcc/cp/lambda.c
index 98fdb74..4d22c3d 100644
--- a/gcc/cp/lambda.c
+++ b/gcc/cp/lambda.c
@@ -793,16 +793,14 @@ lambda_expr_this_capture (tree lambda, bool add_capture_p)
return result;
}
-/* We don't want to capture 'this' until we know we need it, i.e. after
- overload resolution has chosen a non-static member function. At that
- point we call this function to turn a dummy object into a use of the
- 'this' capture. */
+/* Return the current LAMBDA_EXPR, if this is a resolvable dummy
+ object. NULL otherwise.. */
-tree
-maybe_resolve_dummy (tree object, bool add_capture_p)
+static tree
+resolvable_dummy_lambda (tree object)
{
if (!is_dummy_object (object))
- return object;
+ return NULL_TREE;
tree type = TYPE_MAIN_VARIANT (TREE_TYPE (object));
gcc_assert (!TYPE_PTR_P (type));
@@ -812,18 +810,55 @@ maybe_resolve_dummy (tree object, bool add_capture_p)
&& LAMBDA_TYPE_P (current_class_type)
&& lambda_function (current_class_type)
&& DERIVED_FROM_P (type, current_nonlambda_class_type ()))
- {
- /* In a lambda, need to go through 'this' capture. */
- tree lam = CLASSTYPE_LAMBDA_EXPR (current_class_type);
- tree cap = lambda_expr_this_capture (lam, add_capture_p);
- if (cap && cap != error_mark_node)
+ return CLASSTYPE_LAMBDA_EXPR (current_class_type);
+
+ return NULL_TREE;
+}
+
+/* We don't want to capture 'this' until we know we need it, i.e. after
+ overload resolution has chosen a non-static member function. At that
+ point we call this function to turn a dummy object into a use of the
+ 'this' capture. */
+
+tree
+maybe_resolve_dummy (tree object, bool add_capture_p)
+{
+ if (tree lam = resolvable_dummy_lambda (object))
+ if (tree cap = lambda_expr_this_capture (lam, add_capture_p))
+ if (cap != error_mark_node)
object = build_x_indirect_ref (EXPR_LOCATION (object), cap,
RO_NULL, tf_warning_or_error);
- }
return object;
}
+/* When parsing a generic lambda containing an argument-dependent
+ member function call we defer overload resolution to instantiation
+ time. But we have to know now whether to capture this or not.
+ Do that if FNS contains any non-static fns.
+ The std doesn't anticipate this case, but I expect this to be the
+ outcome of discussion. */
+
+void
+maybe_generic_this_capture (tree object, tree fns)
+{
+ if (tree lam = resolvable_dummy_lambda (object))
+ if (!LAMBDA_EXPR_THIS_CAPTURE (lam))
+ {
+ /* We've not yet captured, so look at the function set of
+ interest. */
+ if (BASELINK_P (fns))
+ fns = BASELINK_FUNCTIONS (fns);
+ for (; fns; fns = OVL_NEXT (fns))
+ if (DECL_NONSTATIC_MEMBER_FUNCTION_P (OVL_CURRENT (fns)))
+ {
+ /* Found a non-static member. Capture this. */
+ lambda_expr_this_capture (lam, true);
+ break;
+ }
+ }
+}
+
/* Returns the innermost non-lambda function. */
tree