aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/pt.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/pt.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/pt.c')
-rw-r--r--gcc/cp/pt.c45
1 files changed, 33 insertions, 12 deletions
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index dec7d39..022ffda 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -17142,19 +17142,34 @@ tsubst_copy_and_build (tree t,
if (unq != function)
{
- tree fn = unq;
- if (INDIRECT_REF_P (fn))
- fn = TREE_OPERAND (fn, 0);
- if (TREE_CODE (fn) == COMPONENT_REF)
- fn = TREE_OPERAND (fn, 1);
- if (is_overloaded_fn (fn))
- fn = get_first_fn (fn);
- if (permerror (EXPR_LOC_OR_LOC (t, input_location),
- "%qD was not declared in this scope, "
- "and no declarations were found by "
- "argument-dependent lookup at the point "
- "of instantiation", function))
+ /* In a lambda fn, we have to be careful to not
+ introduce new this captures. Legacy code can't
+ be using lambdas anyway, so it's ok to be
+ stricter. */
+ bool in_lambda = (current_class_type
+ && LAMBDA_TYPE_P (current_class_type));
+ char const *msg = "%qD was not declared in this scope, "
+ "and no declarations were found by "
+ "argument-dependent lookup at the point "
+ "of instantiation";
+
+ bool diag = true;
+ if (in_lambda)
+ error_at (EXPR_LOC_OR_LOC (t, input_location),
+ msg, function);
+ else
+ diag = permerror (EXPR_LOC_OR_LOC (t, input_location),
+ msg, function);
+ if (diag)
{
+ tree fn = unq;
+ if (INDIRECT_REF_P (fn))
+ fn = TREE_OPERAND (fn, 0);
+ if (TREE_CODE (fn) == COMPONENT_REF)
+ fn = TREE_OPERAND (fn, 1);
+ if (is_overloaded_fn (fn))
+ fn = get_first_fn (fn);
+
if (!DECL_P (fn))
/* Can't say anything more. */;
else if (DECL_CLASS_SCOPE_P (fn))
@@ -17177,7 +17192,13 @@ tsubst_copy_and_build (tree t,
inform (DECL_SOURCE_LOCATION (fn),
"%qD declared here, later in the "
"translation unit", fn);
+ if (in_lambda)
+ {
+ release_tree_vector (call_args);
+ RETURN (error_mark_node);
+ }
}
+
function = unq;
}
}