Skip to content

[Clang] use parameter location for abbreviated function templates #129139

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Mar 6, 2025

Conversation

a-tarasyuk
Copy link
Member

Fixes #46386


When an abbreviated function template appears in an extern "C" block and all template parameters are invented, TemplateParams->getTemplateLoc() becomes invalid, leading to an incorrect error location. These changes ensure that the error points to the parameter's location when the template location is invalid.

@a-tarasyuk a-tarasyuk requested a review from cor3ntin February 27, 2025 22:47
@llvmbot llvmbot added clang Clang issues not falling into any other category clang:frontend Language frontend issues, e.g. anything involving "Sema" labels Feb 27, 2025
@llvmbot
Copy link
Member

llvmbot commented Feb 27, 2025

@llvm/pr-subscribers-clang

Author: Oleksandr T. (a-tarasyuk)

Changes

Fixes #46386


When an abbreviated function template appears in an extern "C" block and all template parameters are invented, TemplateParams->getTemplateLoc() becomes invalid, leading to an incorrect error location. These changes ensure that the error points to the parameter's location when the template location is invalid.


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

3 Files Affected:

  • (modified) clang/docs/ReleaseNotes.rst (+1)
  • (modified) clang/lib/Sema/SemaTemplate.cpp (+6-2)
  • (modified) clang/test/CXX/temp/temp.pre/p6.cpp (+15)
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 2b72143482943..902de9f5f012c 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -249,6 +249,7 @@ Bug Fixes to C++ Support
 - The initialization kind of elements of structured bindings
   direct-list-initialized from an array is corrected to direct-initialization.
 - Clang no longer crashes when a coroutine is declared ``[[noreturn]]``. (#GH127327)
+- Clang now uses the parameter location for abbreviated function templates in ``extern "C"``. (#GH46386)
 
 Bug Fixes to AST Handling
 ^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 38fa3ff3ab5b4..3d26428e0a31e 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -7991,8 +7991,12 @@ Sema::CheckTemplateDeclScope(Scope *S, TemplateParameterList *TemplateParams) {
   //   have C linkage.
   DeclContext *Ctx = S->getEntity();
   if (Ctx && Ctx->isExternCContext()) {
-    Diag(TemplateParams->getTemplateLoc(), diag::err_template_linkage)
-        << TemplateParams->getSourceRange();
+    SourceRange Range =
+        TemplateParams->getTemplateLoc().isInvalid() && TemplateParams->size()
+            ? TemplateParams->getParam(TemplateParams->size() - 1)
+                  ->getSourceRange()
+            : TemplateParams->getSourceRange();
+    Diag(Range.getBegin(), diag::err_template_linkage) << Range;
     if (const LinkageSpecDecl *LSD = Ctx->getExternCContext())
       Diag(LSD->getExternLoc(), diag::note_extern_c_begins_here);
     return true;
diff --git a/clang/test/CXX/temp/temp.pre/p6.cpp b/clang/test/CXX/temp/temp.pre/p6.cpp
index cb8c70ca3abed..264972eb44eb3 100644
--- a/clang/test/CXX/temp/temp.pre/p6.cpp
+++ b/clang/test/CXX/temp/temp.pre/p6.cpp
@@ -1,4 +1,19 @@
 // RUN: %clang_cc1 -std=c++20 -verify %s
+// RUN: not %clang_cc1 -std=c++20 -fsyntax-only -fno-diagnostics-show-line-numbers -fcaret-diagnostics-max-lines=1 %s 2>&1 | FileCheck %s -strict-whitespace
+
+namespace GH46386 {
+  extern "C" { // expected-note {{extern "C" language linkage specification begins here}}
+
+  // CHECK:      error: templates must have C++ linkage
+  // CHECK-NEXT: {{^}}  void f(auto) {}
+  // CHECK-NEXT: {{^}}         ^~~~~{{$}}
+  void f(auto) {} // expected-error {{templates must have C++ linkage}}
+
+  void f(void) { // expected-note {{candidate function not viable: requires 0 arguments, but 1 was provided}}
+    f(1);        // expected-error {{no matching function for call to 'f'}}
+  }
+}
+}
 
 // Templates and partial and explicit specializations can't have C linkage.
 namespace extern_c_templates {

@a-tarasyuk a-tarasyuk requested a review from cor3ntin March 5, 2025 15:03
Copy link
Collaborator

@AaronBallman AaronBallman left a comment

Choose a reason for hiding this comment

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

LGTM!

@a-tarasyuk a-tarasyuk merged commit 09e0100 into llvm:main Mar 6, 2025
12 checks passed
jph-13 pushed a commit to jph-13/llvm-project that referenced this pull request Mar 21, 2025
…vm#129139)

Fixes llvm#46386

--- 

When an abbreviated function template appears in an `extern "C"` block
and all template parameters are invented,
`TemplateParams->getTemplateLoc()` becomes invalid, leading to an
incorrect error location. These changes ensure that the error points to
the parameter's location when the template location is invalid.
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.

Abbreviated function template in extern "C" block generates error with bad location
4 participants