https://github.com/arrowten updated 
https://github.com/llvm/llvm-project/pull/192678

>From d82fa62db7f39cfcf459ce8aa9cbaccb4b2e39f8 Mon Sep 17 00:00:00 2001
From: Ajay Wakodikar <[email protected]>
Date: Fri, 8 May 2026 07:49:43 -0400
Subject: [PATCH] [Sema] Reject unqualified lookup of local nested class

---
 clang/lib/Sema/SemaDecl.cpp                   |  9 ++++-
 .../Sema/unqualified-lookup-local-class.cpp   | 39 +++++++++++++++++++
 2 files changed, 46 insertions(+), 2 deletions(-)
 create mode 100644 clang/test/Sema/unqualified-lookup-local-class.cpp

diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index be9654078940f..654682d61ca87 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -1585,8 +1585,13 @@ void Sema::PushOnScopeChains(NamedDecl *D, Scope *S, 
bool AddToContext) {
 
   // Out-of-line definitions shouldn't be pushed into scope in C++, unless they
   // are function-local declarations.
-  if (getLangOpts().CPlusPlus && D->isOutOfLine() && !S->getFnParent())
-    return;
+  if (getLangOpts().CPlusPlus && D->isOutOfLine()) {
+    if (!S->getFnParent())
+      return;
+
+    if (isa<TagDecl>(D) && isa<CXXRecordDecl>(D->getDeclContext()))
+      return;
+  }
 
   // Template instantiations should also not be pushed into scope.
   if (isa<FunctionDecl>(D) &&
diff --git a/clang/test/Sema/unqualified-lookup-local-class.cpp 
b/clang/test/Sema/unqualified-lookup-local-class.cpp
new file mode 100644
index 0000000000000..c87025afe6af8
--- /dev/null
+++ b/clang/test/Sema/unqualified-lookup-local-class.cpp
@@ -0,0 +1,39 @@
+// RUN: %clang_cc1 -std=c++20 -verify %s
+
+struct A1 {
+  int x;
+  void f() { x = 1; } // OK
+};
+
+struct Base {
+  int y;
+};
+
+struct Derived : Base {
+  void f() { y = 2; } // OK
+};
+
+struct A2 { int z; };
+struct B2 : A2 {
+  using A2::z;
+  void f() { z = 3; } // OK
+};
+
+void pass1() {
+  struct A { struct B {}; };
+  A::B b; // OK
+
+  class C { public: class B; };
+  class C::B {};
+  C::B b2; // OK
+}
+
+template<class T>
+struct Wrapper { Wrapper(T) {} };
+
+void fail() {
+  class A { public: class B; };
+  class A::B {};
+  B b;                      // expected-error {{'B'}}
+  Wrapper w = Wrapper{B{}}; // expected-error {{'B'}}
+}

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to