https://github.com/TPPPP72 updated 
https://github.com/llvm/llvm-project/pull/216692

>From 2b554eceedccc8c593f99253bbfa074f8238887a Mon Sep 17 00:00:00 2001
From: Shengxin Pei <[email protected]>
Date: Mon, 17 Aug 2026 21:10:35 +0800
Subject: [PATCH 1/2] [clang] Fixed a crash when declaring a member template
 within a local class inside an OpenMP region

---
 clang/docs/ReleaseNotes.md         |  1 +
 clang/lib/Sema/SemaTemplate.cpp    | 16 ++++++++++++----
 clang/test/SemaOpenMP/gh216052.cpp | 25 +++++++++++++++++++++++++
 3 files changed, 38 insertions(+), 4 deletions(-)
 create mode 100644 clang/test/SemaOpenMP/gh216052.cpp

diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md
index 0e40754efd30e..1fa6c5745b850 100644
--- a/clang/docs/ReleaseNotes.md
+++ b/clang/docs/ReleaseNotes.md
@@ -416,6 +416,7 @@ features cannot lower the translation-unit ABI level;
 - Fixed an ICE that occurred when a structured binding pack is expanded 
outside the lambda where it was declared. (#GH214160)
 - Fixed a bug where a stray closing curley brace in an OpenMP/OpenACC pragma 
could cause pragma parsing issues when inside of a member function. (#GH214195)
 - Fixed a bug where preprocessor directives following comments were not 
correctly recognized when using -C. (#GH48361)
+- Fixed a crash when declaring a member template within a local class inside 
an OpenMP region. (#GH216052)
 
 #### Bug Fixes to Compiler Builtins
 
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index dff681454ae5a..8411d7474bb3f 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -8504,12 +8504,20 @@ Sema::CheckTemplateDeclScope(Scope *S, 
TemplateParameterList *TemplateParams) {
     if (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(Ctx)) {
       // C++ [temp.mem]p2:
       //   A local class shall not have member templates.
-      if (RD->isLocalClass())
+
+      // Trace the outer context chain, bypassing nested records and OpenMP
+      // captured regions, to determine if the class in defined inside a
+      // function or method.
+      const DeclContext *DC = RD->getDeclContext();
+      while (DC && (DC->isRecord() || isa<CapturedDecl>(DC)))
+        DC = DC->getParent();
+
+      if (DC && DC->isFunctionOrMethod())
         return Diag(TemplateParams->getTemplateLoc(),
                     diag::err_template_inside_local_class)
-          << TemplateParams->getSourceRange();
-      else
-        return false;
+               << TemplateParams->getSourceRange();
+
+      return false;
     }
   }
 
diff --git a/clang/test/SemaOpenMP/gh216052.cpp 
b/clang/test/SemaOpenMP/gh216052.cpp
new file mode 100644
index 0000000000000..483b302c3a028
--- /dev/null
+++ b/clang/test/SemaOpenMP/gh216052.cpp
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -fopenmp -fsyntax-only -verify %s
+
+void f1() {
+#pragma omp parallel
+  class O {
+    // expected-error@+1 {{templates cannot be declared inside of a local 
class}}
+    template <class T> class I {
+      void bar(bool b = true);
+    };
+    I<int> bar; // expected-error {{no template named 'I'}}
+  };
+}
+
+void f2() {
+#pragma omp parallel
+  class O {
+    class P {
+      // expected-error@+1 {{templates cannot be declared inside of a local 
class}}
+      template <class T> class I {
+        void bar(bool b = true);
+      };
+      I<int> bar; // expected-error {{no template named 'I'}}
+    };
+  };
+}

>From 6f36ef6061008c922efc26d9bebbf6f5c2967dcc Mon Sep 17 00:00:00 2001
From: Shengxin Pei <[email protected]>
Date: Tue, 18 Aug 2026 10:41:44 +0800
Subject: [PATCH 2/2] use isa_and_nonnull

---
 clang/lib/Sema/SemaTemplate.cpp | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 8411d7474bb3f..c1d8c3500a9a9 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -13,6 +13,7 @@
 #include "clang/AST/ASTConsumer.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/Decl.h"
+#include "clang/AST/DeclCXX.h"
 #include "clang/AST/DeclFriend.h"
 #include "clang/AST/DeclTemplate.h"
 #include "clang/AST/DynamicRecursiveASTVisitor.h"
@@ -8508,11 +8509,11 @@ Sema::CheckTemplateDeclScope(Scope *S, 
TemplateParameterList *TemplateParams) {
       // Trace the outer context chain, bypassing nested records and OpenMP
       // captured regions, to determine if the class in defined inside a
       // function or method.
-      const DeclContext *DC = RD->getDeclContext();
-      while (DC && (DC->isRecord() || isa<CapturedDecl>(DC)))
-        DC = DC->getParent();
+      const DeclContext *OutCtx = RD->getDeclContext();
+      while (isa_and_nonnull<CapturedDecl, CXXRecordDecl>(OutCtx))
+        OutCtx = OutCtx->getParent();
 
-      if (DC && DC->isFunctionOrMethod())
+      if (OutCtx && OutCtx->isFunctionOrMethod())
         return Diag(TemplateParams->getTemplateLoc(),
                     diag::err_template_inside_local_class)
                << TemplateParams->getSourceRange();

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

Reply via email to