Skip to content

Commit 5bf873e

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

File tree

4 files changed

+31
-23
lines changed

4 files changed

+31
-23
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
5658+
: Note<"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: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11183,13 +11183,11 @@ class Sema final : public SemaBase {
1118311183

1118411184
/// Determine whether we would be unable to instantiate this template (because
1118511185
/// it either has no definition, or is in the process of being instantiated).
11186-
bool DiagnoseUninstantiableTemplate(SourceLocation PointOfInstantiation,
11187-
NamedDecl *Instantiation,
11188-
bool InstantiatedFromMember,
11189-
const NamedDecl *Pattern,
11190-
const NamedDecl *PatternDef,
11191-
TemplateSpecializationKind TSK,
11192-
bool Complain = true);
11186+
bool DiagnoseUninstantiableTemplate(
11187+
SourceLocation PointOfInstantiation, NamedDecl *Instantiation,
11188+
bool InstantiatedFromMember, const NamedDecl *Pattern,
11189+
const NamedDecl *PatternDef, TemplateSpecializationKind TSK,
11190+
bool Complain = true, bool *Unreachable = nullptr);
1119311191

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

clang/lib/Sema/SemaTemplate.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -759,13 +759,11 @@ Sema::BuildDependentDeclRefExpr(const CXXScopeSpec &SS,
759759
TemplateArgs);
760760
}
761761

762-
bool Sema::DiagnoseUninstantiableTemplate(SourceLocation PointOfInstantiation,
763-
NamedDecl *Instantiation,
764-
bool InstantiatedFromMember,
765-
const NamedDecl *Pattern,
766-
const NamedDecl *PatternDef,
767-
TemplateSpecializationKind TSK,
768-
bool Complain /*= true*/) {
762+
bool Sema::DiagnoseUninstantiableTemplate(
763+
SourceLocation PointOfInstantiation, NamedDecl *Instantiation,
764+
bool InstantiatedFromMember, const NamedDecl *Pattern,
765+
const NamedDecl *PatternDef, TemplateSpecializationKind TSK,
766+
bool Complain /*= true*/, bool *Unreachable) {
769767
assert(isa<TagDecl>(Instantiation) || isa<FunctionDecl>(Instantiation) ||
770768
isa<VarDecl>(Instantiation));
771769

@@ -778,6 +776,8 @@ bool Sema::DiagnoseUninstantiableTemplate(SourceLocation PointOfInstantiation,
778776
if (!hasReachableDefinition(const_cast<NamedDecl *>(PatternDef),
779777
&SuggestedDef,
780778
/*OnlyNeedComplete*/ false)) {
779+
if (Unreachable)
780+
*Unreachable = true;
781781
// If we're allowed to diagnose this and recover, do so.
782782
bool Recover = Complain && !isSFINAEContext();
783783
if (Complain)

clang/lib/Sema/SemaTemplateInstantiateDecl.cpp

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5052,12 +5052,15 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,
50525052
PatternDef = nullptr;
50535053
}
50545054

5055+
// True is the template definition is unreachable, otherwise false.
5056+
bool Unreachable = false;
50555057
// FIXME: We need to track the instantiation stack in order to know which
50565058
// definitions should be visible within this instantiation.
5057-
if (DiagnoseUninstantiableTemplate(PointOfInstantiation, Function,
5058-
Function->getInstantiatedFromMemberFunction(),
5059-
PatternDecl, PatternDef, TSK,
5060-
/*Complain*/DefinitionRequired)) {
5059+
if (DiagnoseUninstantiableTemplate(
5060+
PointOfInstantiation, Function,
5061+
Function->getInstantiatedFromMemberFunction(), PatternDecl,
5062+
PatternDef, TSK,
5063+
/*Complain*/ DefinitionRequired, &Unreachable)) {
50615064
if (DefinitionRequired)
50625065
Function->setInvalidDecl();
50635066
else if (TSK == TSK_ExplicitInstantiationDefinition ||
@@ -5082,11 +5085,16 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,
50825085
if (AtEndOfTU && !getDiagnostics().hasErrorOccurred() &&
50835086
!getSourceManager().isInSystemHeader(PatternDecl->getBeginLoc())) {
50845087
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;
5088+
<< Function;
5089+
if (Unreachable) {
5090+
Diag(PatternDecl->getLocation(),
5091+
diag::note_unreachable_template_decl);
5092+
} else {
5093+
Diag(PatternDecl->getLocation(), diag::note_forward_template_decl);
5094+
if (getLangOpts().CPlusPlus11)
5095+
Diag(PointOfInstantiation, diag::note_inst_declaration_hint)
5096+
<< Function;
5097+
}
50905098
}
50915099
}
50925100

0 commit comments

Comments
 (0)