https://gcc.gnu.org/g:6d3cc093428e42e0b04f53040f43f9ca1c6f9acb

commit r17-3861-g6d3cc093428e42e0b04f53040f43f9ca1c6f9acb
Author: Lunex <[email protected]>
Date:   Tue Sep 1 13:34:05 2026 +0600

    c++: lookup in enclosing scope when instantiating nested class bases
    
    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]>

Diff:
---
 gcc/cp/pt.cc                                    | 11 ++++++++---
 gcc/testsuite/g++.dg/template/dependent-base7.C | 21 +++++++++++++++++++++
 2 files changed, 29 insertions(+), 3 deletions(-)

diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index ef912d1a7a7a..dd0efa541120 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 000000000000..d443cf7596b6
--- /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>>;

Reply via email to