-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[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
Conversation
@llvm/pr-subscribers-clang Author: Oleksandr T. (a-tarasyuk) ChangesFixes #46386 When an abbreviated function template appears in an Full diff: https://github.com/llvm/llvm-project/pull/129139.diff 3 Files Affected:
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 {
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
…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.
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.