Skip to content

Commit 09e0100

Browse files
authored
[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.
1 parent b21663c commit 09e0100

File tree

3 files changed

+21
-2
lines changed

3 files changed

+21
-2
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,7 @@ Bug Fixes to C++ Support
278278
- The initialization kind of elements of structured bindings
279279
direct-list-initialized from an array is corrected to direct-initialization.
280280
- Clang no longer crashes when a coroutine is declared ``[[noreturn]]``. (#GH127327)
281+
- Clang now uses the parameter location for abbreviated function templates in ``extern "C"``. (#GH46386)
281282

282283
Bug Fixes to AST Handling
283284
^^^^^^^^^^^^^^^^^^^^^^^^^

clang/lib/Sema/SemaTemplate.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7991,8 +7991,11 @@ Sema::CheckTemplateDeclScope(Scope *S, TemplateParameterList *TemplateParams) {
79917991
// have C linkage.
79927992
DeclContext *Ctx = S->getEntity();
79937993
if (Ctx && Ctx->isExternCContext()) {
7994-
Diag(TemplateParams->getTemplateLoc(), diag::err_template_linkage)
7995-
<< TemplateParams->getSourceRange();
7994+
SourceRange Range =
7995+
TemplateParams->getTemplateLoc().isInvalid() && TemplateParams->size()
7996+
? TemplateParams->getParam(0)->getSourceRange()
7997+
: TemplateParams->getSourceRange();
7998+
Diag(Range.getBegin(), diag::err_template_linkage) << Range;
79967999
if (const LinkageSpecDecl *LSD = Ctx->getExternCContext())
79978000
Diag(LSD->getExternLoc(), diag::note_extern_c_begins_here);
79988001
return true;

clang/test/CXX/temp/temp.pre/p6.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,19 @@
11
// RUN: %clang_cc1 -std=c++20 -verify %s
2+
// 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
3+
4+
namespace GH46386 {
5+
extern "C" { // expected-note {{extern "C" language linkage specification begins here}}
6+
7+
// CHECK: error: templates must have C++ linkage
8+
// CHECK-NEXT: {{^}} void f(auto) {}
9+
// CHECK-NEXT: {{^}} ^~~~~{{$}}
10+
void f(auto) {} // expected-error {{templates must have C++ linkage}}
11+
12+
void f(void) { // expected-note {{candidate function not viable: requires 0 arguments, but 1 was provided}}
13+
f(1); // expected-error {{no matching function for call to 'f'}}
14+
}
15+
}
16+
}
217

318
// Templates and partial and explicit specializations can't have C linkage.
419
namespace extern_c_templates {

0 commit comments

Comments
 (0)