diff options
author | Patrick Palka <ppalka@redhat.com> | 2021-05-03 13:35:37 -0400 |
---|---|---|
committer | Patrick Palka <ppalka@redhat.com> | 2021-05-03 13:35:37 -0400 |
commit | 2a6fc19e655e696bf0df9b7aaedf9848b23f07f3 (patch) | |
tree | 8ca05e6d392eb94ded6018a66afc8a50f0b83a69 | |
parent | eef4fa6968ae0682679c27dae06409db3d113d5d (diff) | |
download | gcc-2a6fc19e655e696bf0df9b7aaedf9848b23f07f3.zip gcc-2a6fc19e655e696bf0df9b7aaedf9848b23f07f3.tar.gz gcc-2a6fc19e655e696bf0df9b7aaedf9848b23f07f3.tar.bz2 |
c++: base-clause parsing and implicit 'this' [PR100362]
My r11-6815 change to defer access checking when processing a
base-clause removed a pair of pushclass / popclass calls that seemed to
be unnecessary now that we'd also defer access checking while parsing
the base-clause.
But it turns out these calls make a difference in the below testcase,
where we have a local class whose base-clause implicitly uses the 'this'
of the enclosing class. Before r11-6815, while parsing the base-clause
of the local class, maybe_resolve_dummy would fail to resolve the dummy
'this' object because the current scope would be the local class. Now,
since the current scope is the lambda, maybe_resolve_dummy succeeds and
returns the 'this' for the enclosing class Qux. Later, during deferred
instantiation of the local class, we get confused trying to resolve the
access of 'a_' through this non-dummy 'this'.
So this patch just reinstates the calls to pushclass / popclass that
were removed in r11-6815.
gcc/cp/ChangeLog:
PR c++/100362
* parser.c (cp_parser_class_head): Reinstate calls to pushclass
and popclass when parsing the base-clause that were removed in
r11-6815.
gcc/testsuite/ChangeLog:
PR c++/100362
* g++.dg/cpp1y/lambda-generic-100362.C: New test.
-rw-r--r-- | gcc/cp/parser.c | 8 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp1y/lambda-generic-100362.C | 25 |
2 files changed, 32 insertions, 1 deletions
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 9603a1e..58bd6d1 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -25690,7 +25690,13 @@ cp_parser_class_head (cp_parser* parser, until the entire list has been seen, as per [class.access.general]. */ push_deferring_access_checks (dk_deferred); if (cp_lexer_next_token_is (parser->lexer, CPP_COLON)) - bases = cp_parser_base_clause (parser); + { + if (type) + pushclass (type); + bases = cp_parser_base_clause (parser); + if (type) + popclass (); + } else bases = NULL_TREE; diff --git a/gcc/testsuite/g++.dg/cpp1y/lambda-generic-100362.C b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-100362.C new file mode 100644 index 0000000..283c2c9 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-100362.C @@ -0,0 +1,25 @@ +// PR c++/100362 +// { dg-do compile { target c++14 } } + +template <class> +struct Qux { + struct A { } a_; + A f(); + + void AsyncOp() { + [](auto) { + struct local : decltype(a_) {}; + local ptr; + }(0); + + [](auto) { + struct local : decltype(f()) {}; + local ptr; + }(0); + } +}; + +void corge() { + Qux<int> qux; + qux.AsyncOp(); +} |