[clang] WIP: Improve the -Wundefined-func-template diagnostic note for invisible template functions (PR #129031)
Haojian Wu via cfe-commits
cfe-commits at lists.llvm.org
Fri Feb 28 06:19:39 PST 2025
https://github.com/hokein updated https://github.com/llvm/llvm-project/pull/129031
>From 5bf873e8ab3b97956ca03ef6337baa0f52320003 Mon Sep 17 00:00:00 2001
From: Haojian Wu <hokein.wu at gmail.com>
Date: Thu, 27 Feb 2025 11:15:09 +0100
Subject: [PATCH 1/3] Improve the -Wundefined-func-template diagnostic note for
invisible function templates
---
.../clang/Basic/DiagnosticSemaKinds.td | 2 ++
clang/include/clang/Sema/Sema.h | 12 ++++-----
clang/lib/Sema/SemaTemplate.cpp | 14 +++++-----
.../lib/Sema/SemaTemplateInstantiateDecl.cpp | 26 ++++++++++++-------
4 files changed, 31 insertions(+), 23 deletions(-)
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index f10af8f5bd6b2..8370695912fe1 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -5654,6 +5654,8 @@ def warn_func_template_missing : Warning<"instantiation of function %q0 "
InGroup<UndefinedFuncTemplate>, DefaultIgnore;
def note_forward_template_decl : Note<
"forward declaration of template entity is here">;
+def note_unreachable_template_decl
+ : Note<"declaration of template entity is unreachable here">;
def note_inst_declaration_hint : Note<"add an explicit instantiation "
"declaration to suppress this warning if %q0 is explicitly instantiated in "
"another translation unit">;
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index a501b901862b6..dfe1c0342252f 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -11183,13 +11183,11 @@ class Sema final : public SemaBase {
/// Determine whether we would be unable to instantiate this template (because
/// it either has no definition, or is in the process of being instantiated).
- bool DiagnoseUninstantiableTemplate(SourceLocation PointOfInstantiation,
- NamedDecl *Instantiation,
- bool InstantiatedFromMember,
- const NamedDecl *Pattern,
- const NamedDecl *PatternDef,
- TemplateSpecializationKind TSK,
- bool Complain = true);
+ bool DiagnoseUninstantiableTemplate(
+ SourceLocation PointOfInstantiation, NamedDecl *Instantiation,
+ bool InstantiatedFromMember, const NamedDecl *Pattern,
+ const NamedDecl *PatternDef, TemplateSpecializationKind TSK,
+ bool Complain = true, bool *Unreachable = nullptr);
/// DiagnoseTemplateParameterShadow - Produce a diagnostic complaining
/// that the template parameter 'PrevDecl' is being shadowed by a new
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 38fa3ff3ab5b4..9a0e37f344287 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -759,13 +759,11 @@ Sema::BuildDependentDeclRefExpr(const CXXScopeSpec &SS,
TemplateArgs);
}
-bool Sema::DiagnoseUninstantiableTemplate(SourceLocation PointOfInstantiation,
- NamedDecl *Instantiation,
- bool InstantiatedFromMember,
- const NamedDecl *Pattern,
- const NamedDecl *PatternDef,
- TemplateSpecializationKind TSK,
- bool Complain /*= true*/) {
+bool Sema::DiagnoseUninstantiableTemplate(
+ SourceLocation PointOfInstantiation, NamedDecl *Instantiation,
+ bool InstantiatedFromMember, const NamedDecl *Pattern,
+ const NamedDecl *PatternDef, TemplateSpecializationKind TSK,
+ bool Complain /*= true*/, bool *Unreachable) {
assert(isa<TagDecl>(Instantiation) || isa<FunctionDecl>(Instantiation) ||
isa<VarDecl>(Instantiation));
@@ -778,6 +776,8 @@ bool Sema::DiagnoseUninstantiableTemplate(SourceLocation PointOfInstantiation,
if (!hasReachableDefinition(const_cast<NamedDecl *>(PatternDef),
&SuggestedDef,
/*OnlyNeedComplete*/ false)) {
+ if (Unreachable)
+ *Unreachable = true;
// If we're allowed to diagnose this and recover, do so.
bool Recover = Complain && !isSFINAEContext();
if (Complain)
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 1f42f9500959e..f5071e9835e36 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -5052,12 +5052,15 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,
PatternDef = nullptr;
}
+ // True is the template definition is unreachable, otherwise false.
+ bool Unreachable = false;
// FIXME: We need to track the instantiation stack in order to know which
// definitions should be visible within this instantiation.
- if (DiagnoseUninstantiableTemplate(PointOfInstantiation, Function,
- Function->getInstantiatedFromMemberFunction(),
- PatternDecl, PatternDef, TSK,
- /*Complain*/DefinitionRequired)) {
+ if (DiagnoseUninstantiableTemplate(
+ PointOfInstantiation, Function,
+ Function->getInstantiatedFromMemberFunction(), PatternDecl,
+ PatternDef, TSK,
+ /*Complain*/ DefinitionRequired, &Unreachable)) {
if (DefinitionRequired)
Function->setInvalidDecl();
else if (TSK == TSK_ExplicitInstantiationDefinition ||
@@ -5082,11 +5085,16 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,
if (AtEndOfTU && !getDiagnostics().hasErrorOccurred() &&
!getSourceManager().isInSystemHeader(PatternDecl->getBeginLoc())) {
Diag(PointOfInstantiation, diag::warn_func_template_missing)
- << Function;
- Diag(PatternDecl->getLocation(), diag::note_forward_template_decl);
- if (getLangOpts().CPlusPlus11)
- Diag(PointOfInstantiation, diag::note_inst_declaration_hint)
- << Function;
+ << Function;
+ if (Unreachable) {
+ Diag(PatternDecl->getLocation(),
+ diag::note_unreachable_template_decl);
+ } else {
+ Diag(PatternDecl->getLocation(), diag::note_forward_template_decl);
+ if (getLangOpts().CPlusPlus11)
+ Diag(PointOfInstantiation, diag::note_inst_declaration_hint)
+ << Function;
+ }
}
}
>From b24cbb918fe9d2ecb75470d68b3633d8bc68cc32 Mon Sep 17 00:00:00 2001
From: Haojian Wu <hokein.wu at gmail.com>
Date: Fri, 28 Feb 2025 14:40:41 +0100
Subject: [PATCH 2/3] Add a lit test.
---
clang/test/Modules/Inputs/undefined-template/hoge.h | 7 +++++++
.../Modules/Inputs/undefined-template/module.modulemap | 7 +++++++
.../Modules/Inputs/undefined-template/shared_ptr2.h | 4 ++++
clang/test/Modules/diag-undefined-template.cpp | 10 ++++++++++
4 files changed, 28 insertions(+)
create mode 100644 clang/test/Modules/Inputs/undefined-template/hoge.h
create mode 100644 clang/test/Modules/Inputs/undefined-template/module.modulemap
create mode 100644 clang/test/Modules/Inputs/undefined-template/shared_ptr2.h
create mode 100644 clang/test/Modules/diag-undefined-template.cpp
diff --git a/clang/test/Modules/Inputs/undefined-template/hoge.h b/clang/test/Modules/Inputs/undefined-template/hoge.h
new file mode 100644
index 0000000000000..c67e85ed06734
--- /dev/null
+++ b/clang/test/Modules/Inputs/undefined-template/hoge.h
@@ -0,0 +1,7 @@
+#pragma once
+
+#include "shared_ptr2.h"
+
+inline void f() {
+ x<int>();
+}
diff --git a/clang/test/Modules/Inputs/undefined-template/module.modulemap b/clang/test/Modules/Inputs/undefined-template/module.modulemap
new file mode 100644
index 0000000000000..89cc78cd5a2de
--- /dev/null
+++ b/clang/test/Modules/Inputs/undefined-template/module.modulemap
@@ -0,0 +1,7 @@
+module hoge {
+ header "hoge.h"
+}
+
+module shared_ptr2 {
+ header "shared_ptr2.h"
+}
diff --git a/clang/test/Modules/Inputs/undefined-template/shared_ptr2.h b/clang/test/Modules/Inputs/undefined-template/shared_ptr2.h
new file mode 100644
index 0000000000000..495cc6fe539c1
--- /dev/null
+++ b/clang/test/Modules/Inputs/undefined-template/shared_ptr2.h
@@ -0,0 +1,4 @@
+#pragma once
+
+template<class T>
+void x() { }
diff --git a/clang/test/Modules/diag-undefined-template.cpp b/clang/test/Modules/diag-undefined-template.cpp
new file mode 100644
index 0000000000000..79b1586a702cc
--- /dev/null
+++ b/clang/test/Modules/diag-undefined-template.cpp
@@ -0,0 +1,10 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -std=c++20 -fmodules -fmodules-cache-path=%t -I%S/Inputs/undefined-template \
+// RUN: -Wundefined-func-template \
+// RUN: -fimplicit-module-maps %s 2>&1 | grep "declaration of template entity is unreachable here"
+
+#include "hoge.h"
+
+int main() {
+ f();
+}
>From 2cb0ad367c250912a2883f2b190e73ad37ab182e Mon Sep 17 00:00:00 2001
From: Haojian Wu <hokein.wu at gmail.com>
Date: Fri, 28 Feb 2025 15:19:06 +0100
Subject: [PATCH 3/3] Address review comments
---
clang/include/clang/Basic/DiagnosticSemaKinds.td | 2 +-
clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | 2 ++
clang/test/Modules/diag-undefined-template.cpp | 2 +-
3 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 8370695912fe1..80f2d54c8a893 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -5655,7 +5655,7 @@ def warn_func_template_missing : Warning<"instantiation of function %q0 "
def note_forward_template_decl : Note<
"forward declaration of template entity is here">;
def note_unreachable_template_decl
- : Note<"declaration of template entity is unreachable here">;
+ : Note<"unreachable declaration of template entity is here">;
def note_inst_declaration_hint : Note<"add an explicit instantiation "
"declaration to suppress this warning if %q0 is explicitly instantiated in "
"another translation unit">;
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index f5071e9835e36..398e41b236ae4 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -5087,6 +5087,8 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,
Diag(PointOfInstantiation, diag::warn_func_template_missing)
<< Function;
if (Unreachable) {
+ // FIXME: would be nice to mention which module the function template
+ // comes from.
Diag(PatternDecl->getLocation(),
diag::note_unreachable_template_decl);
} else {
diff --git a/clang/test/Modules/diag-undefined-template.cpp b/clang/test/Modules/diag-undefined-template.cpp
index 79b1586a702cc..027984c3125f3 100644
--- a/clang/test/Modules/diag-undefined-template.cpp
+++ b/clang/test/Modules/diag-undefined-template.cpp
@@ -1,7 +1,7 @@
// RUN: rm -rf %t
// RUN: %clang_cc1 -std=c++20 -fmodules -fmodules-cache-path=%t -I%S/Inputs/undefined-template \
// RUN: -Wundefined-func-template \
-// RUN: -fimplicit-module-maps %s 2>&1 | grep "declaration of template entity is unreachable here"
+// RUN: -fimplicit-module-maps %s 2>&1 | grep "unreachable declaration of template entity is her"
#include "hoge.h"
More information about the cfe-commits
mailing list