c++: static memfn from non-dependent base [PR101078]
authorJason Merrill <jason@redhat.com>
Wed, 16 Jun 2021 20:09:59 +0000 (16:09 -0400)
committerJason Merrill <jason@redhat.com>
Wed, 16 Jun 2021 21:28:36 +0000 (17:28 -0400)
After my patch for PR91706, or before that with the qualified call,
tsubst_baselink returned a BASELINK with BASELINK_BINFO indicating a base of
a still-dependent derived class.  We need to look up the relevant base binfo
in the substituted class.

PR c++/101078
PR c++/91706

gcc/cp/ChangeLog:

* pt.c (tsubst_baselink): Update binfos in non-dependent case.

gcc/testsuite/ChangeLog:

* g++.dg/template/access39.C: New test.

gcc/cp/pt.c
gcc/testsuite/g++.dg/template/access39.C [new file with mode: 0644]

index d4bb5cc..15947b2 100644 (file)
@@ -16249,8 +16249,19 @@ tsubst_baselink (tree baselink, tree object_type,
        fns = BASELINK_FUNCTIONS (baselink);
     }
   else
-    /* We're going to overwrite pieces below, make a duplicate.  */
-    baselink = copy_node (baselink);
+    {
+      /* We're going to overwrite pieces below, make a duplicate.  */
+      baselink = copy_node (baselink);
+
+      if (qualifying_scope != BINFO_TYPE (BASELINK_ACCESS_BINFO (baselink)))
+       {
+         /* The decl we found was from non-dependent scope, but we still need
+            to update the binfos for the instantiated qualifying_scope.  */
+         BASELINK_ACCESS_BINFO (baselink) = TYPE_BINFO (qualifying_scope);
+         BASELINK_BINFO (baselink) = lookup_base (qualifying_scope, binfo_type,
+                                                  ba_unique, nullptr, complain);
+       }
+    }
 
   /* If lookup found a single function, mark it as used at this point.
      (If lookup found multiple functions the one selected later by
diff --git a/gcc/testsuite/g++.dg/template/access39.C b/gcc/testsuite/g++.dg/template/access39.C
new file mode 100644 (file)
index 0000000..d941555
--- /dev/null
@@ -0,0 +1,17 @@
+// PR c++/101078
+
+struct A {
+  static void f();
+};
+
+template<class>
+struct B : private A {
+  struct C {
+    void g() { f(); }
+    void g2() { B::f(); }
+  };
+};
+
+int main() {
+  B<int>::C().g();
+}