Skip to content

Commit ccd5da1

Browse files
committed
Improve the -Wundefined-func-template diagnostic note for invisible function
templates
1 parent 262e4c1 commit ccd5da1

File tree

4 files changed

+27
-11
lines changed

4 files changed

+27
-11
lines changed

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5654,6 +5654,8 @@ def warn_func_template_missing : Warning<"instantiation of function %q0 "
56545654
InGroup<UndefinedFuncTemplate>, DefaultIgnore;
56555655
def note_forward_template_decl : Note<
56565656
"forward declaration of template entity is here">;
5657+
def note_unreachable_template_decl : Note<
5658+
"declaration of template entity is unreachable here">;
56575659
def note_inst_declaration_hint : Note<"add an explicit instantiation "
56585660
"declaration to suppress this warning if %q0 is explicitly instantiated in "
56595661
"another translation unit">;

clang/include/clang/Sema/Sema.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11189,7 +11189,8 @@ class Sema final : public SemaBase {
1118911189
const NamedDecl *Pattern,
1119011190
const NamedDecl *PatternDef,
1119111191
TemplateSpecializationKind TSK,
11192-
bool Complain = true);
11192+
bool Complain = true,
11193+
bool* Unreachable = nullptr);
1119311194

1119411195
/// DiagnoseTemplateParameterShadow - Produce a diagnostic complaining
1119511196
/// that the template parameter 'PrevDecl' is being shadowed by a new

clang/lib/Sema/SemaTemplate.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -765,7 +765,8 @@ bool Sema::DiagnoseUninstantiableTemplate(SourceLocation PointOfInstantiation,
765765
const NamedDecl *Pattern,
766766
const NamedDecl *PatternDef,
767767
TemplateSpecializationKind TSK,
768-
bool Complain /*= true*/) {
768+
bool Complain /*= true*/,
769+
bool* Unreachable) {
769770
assert(isa<TagDecl>(Instantiation) || isa<FunctionDecl>(Instantiation) ||
770771
isa<VarDecl>(Instantiation));
771772

@@ -778,6 +779,8 @@ bool Sema::DiagnoseUninstantiableTemplate(SourceLocation PointOfInstantiation,
778779
if (!hasReachableDefinition(const_cast<NamedDecl *>(PatternDef),
779780
&SuggestedDef,
780781
/*OnlyNeedComplete*/ false)) {
782+
if (Unreachable)
783+
*Unreachable = true;
781784
// If we're allowed to diagnose this and recover, do so.
782785
bool Recover = Complain && !isSFINAEContext();
783786
if (Complain)

clang/lib/Sema/SemaTemplateInstantiateDecl.cpp

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "clang/AST/ExprCXX.h"
2121
#include "clang/AST/PrettyDeclStackTrace.h"
2222
#include "clang/AST/TypeLoc.h"
23+
#include "clang/Basic/DiagnosticParse.h"
2324
#include "clang/Basic/SourceManager.h"
2425
#include "clang/Basic/TargetInfo.h"
2526
#include "clang/Sema/EnterExpressionEvaluationContext.h"
@@ -34,6 +35,7 @@
3435
#include "clang/Sema/SemaSwift.h"
3536
#include "clang/Sema/Template.h"
3637
#include "clang/Sema/TemplateInstCallback.h"
38+
#include "llvm/Support/Signals.h"
3739
#include "llvm/Support/TimeProfiler.h"
3840
#include <optional>
3941

@@ -5052,12 +5054,15 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,
50525054
PatternDef = nullptr;
50535055
}
50545056

5057+
// True is the template definition is unreachable, otherwise false.
5058+
bool Unreachable = false;
50555059
// FIXME: We need to track the instantiation stack in order to know which
50565060
// definitions should be visible within this instantiation.
5057-
if (DiagnoseUninstantiableTemplate(PointOfInstantiation, Function,
5058-
Function->getInstantiatedFromMemberFunction(),
5059-
PatternDecl, PatternDef, TSK,
5060-
/*Complain*/DefinitionRequired)) {
5061+
if (DiagnoseUninstantiableTemplate(
5062+
PointOfInstantiation, Function,
5063+
Function->getInstantiatedFromMemberFunction(), PatternDecl,
5064+
PatternDef, TSK,
5065+
/*Complain*/ DefinitionRequired, &Unreachable)) {
50615066
if (DefinitionRequired)
50625067
Function->setInvalidDecl();
50635068
else if (TSK == TSK_ExplicitInstantiationDefinition ||
@@ -5082,11 +5087,16 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,
50825087
if (AtEndOfTU && !getDiagnostics().hasErrorOccurred() &&
50835088
!getSourceManager().isInSystemHeader(PatternDecl->getBeginLoc())) {
50845089
Diag(PointOfInstantiation, diag::warn_func_template_missing)
5085-
<< Function;
5086-
Diag(PatternDecl->getLocation(), diag::note_forward_template_decl);
5087-
if (getLangOpts().CPlusPlus11)
5088-
Diag(PointOfInstantiation, diag::note_inst_declaration_hint)
5089-
<< Function;
5090+
<< Function;
5091+
if (Unreachable) {
5092+
Diag(PatternDecl->getLocation(),
5093+
diag::note_unreachable_template_decl);
5094+
} else {
5095+
Diag(PatternDecl->getLocation(), diag::note_forward_template_decl);
5096+
if (getLangOpts().CPlusPlus11)
5097+
Diag(PointOfInstantiation, diag::note_inst_declaration_hint)
5098+
<< Function;
5099+
}
50905100
}
50915101
}
50925102

0 commit comments

Comments
 (0)