[clang] 09e0100 - [Clang] use parameter location for abbreviated function templates (#129139)
via cfe-commits
cfe-commits at lists.llvm.org
Thu Mar 6 05:12:56 PST 2025
Author: Oleksandr T.
Date: 2025-03-06T15:12:53+02:00
New Revision: 09e010001773d7d7efc0cafe78d3c8899d8bc45d
URL: https://github.com/llvm/llvm-project/commit/09e010001773d7d7efc0cafe78d3c8899d8bc45d
DIFF: https://github.com/llvm/llvm-project/commit/09e010001773d7d7efc0cafe78d3c8899d8bc45d.diff
LOG: [Clang] use parameter location for abbreviated function templates (#129139)
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.
Added:
Modified:
clang/docs/ReleaseNotes.rst
clang/lib/Sema/SemaTemplate.cpp
clang/test/CXX/temp/temp.pre/p6.cpp
Removed:
################################################################################
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 2576801aff708..86bf836b4a999 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -278,6 +278,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 fcbbf5dbffa53..7ffcef1592a93 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -7991,8 +7991,11 @@ 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(0)->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 {
More information about the cfe-commits
mailing list