]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c++: base-clause parsing and implicit 'this' [PR100362]
authorPatrick Palka <ppalka@redhat.com>
Mon, 3 May 2021 17:35:37 +0000 (13:35 -0400)
committerPatrick Palka <ppalka@redhat.com>
Mon, 3 May 2021 17:41:23 +0000 (13:41 -0400)
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.

(cherry picked from commit 2a6fc19e655e696bf0df9b7aaedf9848b23f07f3)

gcc/cp/parser.c
gcc/testsuite/g++.dg/cpp1y/lambda-generic-100362.C [new file with mode: 0644]

index fba516efa23d5e74d59bf9f36e825bdce3fe9b54..a3dae3164ce14a4fe1cd25e946ddbfee583018ef 100644 (file)
@@ -25680,7 +25680,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 (file)
index 0000000..283c2c9
--- /dev/null
@@ -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();
+}