diff options
author | Nathan Sidwell <nathan@acm.org> | 2017-01-17 18:22:34 +0000 |
---|---|---|
committer | Nathan Sidwell <nathan@gcc.gnu.org> | 2017-01-17 18:22:34 +0000 |
commit | 8ddfdbc265cfe0da5b727559d3736876d0198afb (patch) | |
tree | 127551e9b5d51e1763e5a76af78e43a959b28a43 /gcc/cp/pt.c | |
parent | f46fe37e86aa04522258dad374d0c7bf9c443ed3 (diff) | |
download | gcc-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.c | 45 |
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; } } |