On 9/1/26 3:34 AM, [email protected] wrote:
From: Lunex <[email protected]>

Thanks for the patch!  I'm pushing it with some adjustments.

This patch is trivial enough not to worry about copyright, but if you want to continue contributing under this pseudonym I encourage you to file a copyright assignment with the FSF. See https://gcc.gnu.org/contribute.html#legal for more information.

PR c++/114804

For future reference, the PR number should go at the top of the ChangeLog entries.
r11-6815 (PR 82613) removed push_scope/pop_scope around base-clause
substitution in instantiate_class_template. This broke lookup for
using-declarations that bring enclosing-class members into scope
during nested class instantiation.

This restores the enclosing-class scope push/pop that was there before
r11-6815.

gcc/cp/ChangeLog:
        * pt.cc (instantiate_class_template): Push enclosing class scope
        before base substitution, pop after.

gcc/testsuite/ChangeLog:
        * g++.dg/template/pr114804.C: New test.

And please name testcases by what they are testing, not just the PR; I've renamed it to dependent-base7.C.

@@ -13093,6 +13096,9 @@ instantiate_class_template (tree type)
      information.  */
   xref_basetypes (type, base_list);
+ if (pushed_scope)
+    pop_scope (pushed_scope);
+
   apply_late_template_attributes (&type, TYPE_ATTRIBUTES (pattern),
                                  (int) ATTR_FLAG_TYPE_IN_PLACE,
                                  args, tf_error, NULL_TREE);

It occurred to me that rather than pop all the way out and then almost immediately push_nested_class again, we could stay in the enclosing scope and only push one level into the class we're defining.

+++ b/gcc/testsuite/g++.dg/template/pr114804.C
@@ -0,0 +1,21 @@
+// PR c++/114804
+// { dg-do compile }

Also this needs { target c++11 } to avoid FAILing in C++98 mode. How did you test the patch?

Here's what I'm pushing:

From 6d3cc093428e42e0b04f53040f43f9ca1c6f9acb Mon Sep 17 00:00:00 2001
From: Lunex <[email protected]>
Date: Tue, 1 Sep 2026 13:34:05 +0600
Subject: [PATCH] c++: lookup in enclosing scope when instantiating nested
 class bases
To: [email protected]

r11-6815 (PR 82613) removed push_scope/pop_scope around base-clause
substitution in instantiate_class_template. This broke lookup for
using-declarations that bring enclosing-class members into scope
during nested class instantiation.

So let's restore the push_scope.  But rather than pop_scope after the bases
and then immediately push_nested_class, we can move the pop_scope to the end
of the function and just pushclass/popclass for the class itself.

	PR c++/114804

gcc/cp/ChangeLog:
	* pt.cc (instantiate_class_template): Push enclosing scope
	before base substitution, pop at the end.

gcc/testsuite/ChangeLog:
	* g++.dg/template/dependent-base7.C: New test.

Co-authored-by: Jason Merrill <[email protected]>
---
 gcc/cp/pt.cc                                  | 11 +++++++---
 .../g++.dg/template/dependent-base7.C         | 21 +++++++++++++++++++
 2 files changed, 29 insertions(+), 3 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/template/dependent-base7.C

diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index ef912d1a7a7..dd0efa54112 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -13025,6 +13025,10 @@ instantiate_class_template (tree type)
   /* Defer access checking while we substitute into the types named in
      the base-clause.  */
   push_deferring_access_checks (dk_deferred);
+
+  /* Push into the containing scope for name lookup (114804).  */
+  tree pushed_scope = push_scope (CP_TYPE_CONTEXT (type));
+
   if (BINFO_N_BASE_BINFOS (pbinfo))
     {
       tree pbase_binfo;
@@ -13102,8 +13106,8 @@ instantiate_class_template (tree type)
      class, so that name lookups into base classes, etc. will work
      correctly.  This is precisely analogous to what we do in
      begin_class_definition when defining an ordinary non-template
-     class, except we also need to push the enclosing classes.  */
-  push_nested_class (type);
+     class.  */
+  pushclass (type);
 
   /* Now check accessibility of the types named in its base-clause,
      relative to the scope of the class.  */
@@ -13425,7 +13429,8 @@ instantiate_class_template (tree type)
   for (tree x : used)
     mark_used (x);
 
-  pop_nested_class ();
+  popclass ();
+  pop_scope (pushed_scope);
   maximum_field_alignment = saved_maximum_field_alignment;
   if (!fn_context)
     pop_from_top_level ();
diff --git a/gcc/testsuite/g++.dg/template/dependent-base7.C b/gcc/testsuite/g++.dg/template/dependent-base7.C
new file mode 100644
index 00000000000..d443cf7596b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/dependent-base7.C
@@ -0,0 +1,21 @@
+// PR c++/114804
+// { dg-do compile { target c++11 } }
+
+template <int D> struct blurb
+{
+  constexpr static int d = D;
+};
+
+template <int> struct pant
+{
+};
+
+template <typename Base> struct bug : Base
+{
+  using Base::d;
+  struct problem : pant<d>
+  {
+  };
+};
+
+template struct bug<blurb<2>>;
-- 
2.55.0

Reply via email to