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..fe7da132b4ffe 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 {