Skip to content

Conversation

@Sandeep2265
Copy link

edited in the file SemaTemplate.cpp and also added few testcases.

…Template.cpp and also added few testcase.
@github-actions
Copy link

github-actions bot commented Nov 9, 2025

Thank you for submitting a Pull Request (PR) to the LLVM Project!

This PR will be automatically labeled and the relevant teams will be notified.

If you wish to, you can add reviewers by using the "Reviewers" section on this page.

If this is not working for you, it is probably because you do not have write permissions for the repository. In which case you can instead tag reviewers by name in a comment by using @ followed by their GitHub username.

If you have received no comments on your PR for a week, you can request a review by "ping"ing the PR by adding a comment “Ping”. The common courtesy "ping" rate is once a week. Please remember that you are asking for valuable time from other developers.

If you have further questions, they may be answered by the LLVM GitHub User Guide.

You can also ask questions in a comment on this PR, on the LLVM Discord or on the forums.

@llvmbot llvmbot added clang Clang issues not falling into any other category clang:frontend Language frontend issues, e.g. anything involving "Sema" labels Nov 9, 2025
@llvmbot
Copy link
Member

llvmbot commented Nov 9, 2025

@llvm/pr-subscribers-clang

Author: None (Sandeep2265)

Changes

edited in the file SemaTemplate.cpp and also added few testcases.


Full diff: https://github.com/llvm/llvm-project/pull/167228.diff

7 Files Affected:

  • (modified) clang/lib/Sema/SemaTemplate.cpp (+35-19)
  • (added) clang/test/SemaCXX/lambda-local-c++17.cpp (+11)
  • (added) clang/test/SemaCXX/lambda-local-c++20.cpp (+11)
  • (added) clang/test/SemaCXX/nested-local.cpp (+9)
  • (added) clang/test/SemaCXX/static-local.cpp (+8)
  • (added) clang/test/SemaCXX/template-member-local-c++17.cpp (+16)
  • (added) clang/test/SemaCXX/template-member-local-c++20.cpp (+16)
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 4a9e1bc93b918..ba91b25fc1843 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -8421,7 +8421,7 @@ bool Sema::TemplateParameterListsAreEqual(
   return true;
 }
 
-bool
+bool 
 Sema::CheckTemplateDeclScope(Scope *S, TemplateParameterList *TemplateParams) {
   if (!S)
     return false;
@@ -8445,33 +8445,49 @@ Sema::CheckTemplateDeclScope(Scope *S, TemplateParameterList *TemplateParams) {
   }
   Ctx = Ctx ? Ctx->getRedeclContext() : nullptr;
 
-  // C++ [temp]p2:
-  //   A template-declaration can appear only as a namespace scope or
-  //   class scope declaration.
-  // C++ [temp.expl.spec]p3:
-  //   An explicit specialization may be declared in any scope in which the
-  //   corresponding primary template may be defined.
-  // C++ [temp.class.spec]p6: [P2096]
-  //   A partial specialization may be declared in any scope in which the
-  //   corresponding primary template may be defined.
+  // Compute a SourceLocation to use for diagnostics. Prefer the explicit
+  // template location, but fall back to nearby Decl locations when needed.
+  SourceLocation Loc = TemplateParams->getTemplateLoc();
+  if (Loc.isInvalid())
+    Loc = TemplateParams->getSourceRange().getBegin();
+
+  if (Loc.isInvalid() && Ctx) {
+    if (const Decl *D = dyn_cast<Decl>(Ctx))
+      Loc = D->getBeginLoc();
+  }
+
+  // Try to extract class context if present.
+  CXXRecordDecl *RD = Ctx ? dyn_cast<CXXRecordDecl>(Ctx) : nullptr;
+  if (Loc.isInvalid() && RD)
+    Loc = RD->getLocation();
+
   if (Ctx) {
     if (Ctx->isFileContext())
       return false;
-    if (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(Ctx)) {
+
+    if (RD) {
       // C++ [temp.mem]p2:
       //   A local class shall not have member templates.
-      if (RD->isLocalClass())
-        return Diag(TemplateParams->getTemplateLoc(),
-                    diag::err_template_inside_local_class)
-          << TemplateParams->getSourceRange();
-      else
+      if (RD->isLocalClass()) {
+        // when the template location is not valid we are trying to use fallback SourceLocation such that diagnostic prints a usable file:line:col location
+        if (Loc.isInvalid())
+          Loc = TemplateParams->getSourceRange().getBegin();
+
+        return Diag(Loc, diag::err_template_inside_local_class)
+                 << TemplateParams->getSourceRange();
+      } 
+      else {
         return false;
+      }
     }
   }
 
-  return Diag(TemplateParams->getTemplateLoc(),
-              diag::err_template_outside_namespace_or_class_scope)
-    << TemplateParams->getSourceRange();
+  // when teplate declared outside the namspace or class scope it Fallbacks and it give valid SourceLocation with file:line info.
+  if (Loc.isInvalid())
+    Loc = TemplateParams->getSourceRange().getBegin();
+
+  return Diag(Loc, diag::err_template_outside_namespace_or_class_scope)
+           << TemplateParams->getSourceRange();
 }
 
 /// Determine what kind of template specialization the given declaration
diff --git a/clang/test/SemaCXX/lambda-local-c++17.cpp b/clang/test/SemaCXX/lambda-local-c++17.cpp
new file mode 100644
index 0000000000000..0d23849fa5cab
--- /dev/null
+++ b/clang/test/SemaCXX/lambda-local-c++17.cpp
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+int main() {
+  auto L = []() {
+    struct LocalInLambda {
+      void qux(auto x) {} // expected-error {{'auto' not allowed in function prototype}}
+    };
+    (void)sizeof(LocalInLambda);
+  };
+  L();
+}
\ No newline at end of file
diff --git a/clang/test/SemaCXX/lambda-local-c++20.cpp b/clang/test/SemaCXX/lambda-local-c++20.cpp
new file mode 100644
index 0000000000000..1fc82d928a6b3
--- /dev/null
+++ b/clang/test/SemaCXX/lambda-local-c++20.cpp
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++20 -verify %s
+
+int main() {
+  auto L = []() {
+    struct LocalInLambda { // expected-error {{templates cannot be declared inside of a local class}}
+      void qux(auto x) {}
+    };
+    (void)sizeof(LocalInLambda);
+  };
+  L();
+}
diff --git a/clang/test/SemaCXX/nested-local.cpp b/clang/test/SemaCXX/nested-local.cpp
new file mode 100644
index 0000000000000..e776979b4582b
--- /dev/null
+++ b/clang/test/SemaCXX/nested-local.cpp
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++17 -verify %s
+
+void fn() {
+  struct Outer {
+    struct Inner {
+      void foo(auto x) {} // expected-error {{'auto' not allowed in function prototype}}
+    };
+  };
+}
diff --git a/clang/test/SemaCXX/static-local.cpp b/clang/test/SemaCXX/static-local.cpp
new file mode 100644
index 0000000000000..7c8d378e0e247
--- /dev/null
+++ b/clang/test/SemaCXX/static-local.cpp
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++20 -verify %s
+
+int main() {
+  static struct StaticLocal { // expected-error {{templates cannot be declared inside of a local class}}
+    void bar(auto x) {}
+  } s;
+  (void)s;
+}
diff --git a/clang/test/SemaCXX/template-member-local-c++17.cpp b/clang/test/SemaCXX/template-member-local-c++17.cpp
new file mode 100644
index 0000000000000..237d400118888
--- /dev/null
+++ b/clang/test/SemaCXX/template-member-local-c++17.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<typename T>
+struct Outer {
+  void member() {
+    struct Local {
+      void baz(auto x) {} // expected-error {{'auto' not allowed in function prototype}}
+    };
+    (void)sizeof(Local);
+  }
+};
+
+int main() {
+  Outer<int> o;
+  o.member();
+}
diff --git a/clang/test/SemaCXX/template-member-local-c++20.cpp b/clang/test/SemaCXX/template-member-local-c++20.cpp
new file mode 100644
index 0000000000000..86ade46eebbf4
--- /dev/null
+++ b/clang/test/SemaCXX/template-member-local-c++20.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++20 -verify %s
+
+template<typename T>
+struct Outer {
+  void member() {
+    struct Local { // expected-error {{templates cannot be declared inside of a local class}}
+      void baz(auto x) {}
+    };
+    (void)sizeof(Local);
+  }
+};
+
+int main() {
+  Outer<int> o;
+  o.member();
+}

Copy link
Contributor

@zyn0217 zyn0217 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please stop flooding our review list with low-quality, LLM-generated PRs.

It's unacceptable that some of you remain obsessed with this specific issue, despite the fact that a (seemingly) proper fix was already submitted months ago: #149781

Unless you can clearly explain what you are doing and demonstrate understanding of the codebase, we will not trust or accept any further patches you submit. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

clang:frontend Language frontend issues, e.g. anything involving "Sema" clang Clang issues not falling into any other category

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants