Skip to content

Commit a36dcb0

Browse files
committed
[clang] print correct context for diagnostics suppressed by deduction
This patch makes it so the correct instantiation context is printed for diagnostics suppessed by template argument deduction. The context is saved along with the suppressed diagnostic, and when the declaration they were attached to becomes used, we print the correct context, instead of whatever context was at this point.
1 parent 4eab219 commit a36dcb0

18 files changed

+211
-161
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,8 @@ Bug Fixes to C++ Support
146146
^^^^^^^^^^^^^^^^^^^^^^^^
147147

148148
- Clang is now better at keeping track of friend function template instance contexts. (#GH55509)
149+
- Clang now prints the correct instantiation context for diagnostics suppressed
150+
by template argument deduction.
149151

150152
Bug Fixes to AST Handling
151153
^^^^^^^^^^^^^^^^^^^^^^^^^

clang/include/clang/Sema/Sema.h

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1909,7 +1909,22 @@ class Sema final : public SemaBase {
19091909
/// '\#pragma clang attribute push' directives to the given declaration.
19101910
void AddPragmaAttributes(Scope *S, Decl *D);
19111911

1912-
void PrintPragmaAttributeInstantiationPoint();
1912+
using DiagFuncRef =
1913+
llvm::function_ref<void(SourceLocation, PartialDiagnostic)>;
1914+
auto getDefaultDiagFunc() {
1915+
return [this](SourceLocation Loc, PartialDiagnostic PD) {
1916+
// This bypasses a lof of the filters in the diag engine, as it's
1917+
// to be used to attach notes to diagnostics which have already
1918+
// been filtered through.
1919+
DiagnosticBuilder Builder(Diags.Report(Loc, PD.getDiagID()));
1920+
PD.Emit(Builder);
1921+
};
1922+
}
1923+
1924+
void PrintPragmaAttributeInstantiationPoint(DiagFuncRef DiagFunc);
1925+
void PrintPragmaAttributeInstantiationPoint() {
1926+
PrintPragmaAttributeInstantiationPoint(getDefaultDiagFunc());
1927+
}
19131928

19141929
void DiagnoseUnterminatedPragmaAttribute();
19151930

@@ -13263,18 +13278,22 @@ class Sema final : public SemaBase {
1326313278
void pushCodeSynthesisContext(CodeSynthesisContext Ctx);
1326413279
void popCodeSynthesisContext();
1326513280

13266-
void PrintContextStack() {
13281+
void PrintContextStack(DiagFuncRef DiagFunc) {
1326713282
if (!CodeSynthesisContexts.empty() &&
1326813283
CodeSynthesisContexts.size() != LastEmittedCodeSynthesisContextDepth) {
13269-
PrintInstantiationStack();
13284+
PrintInstantiationStack(DiagFunc);
1327013285
LastEmittedCodeSynthesisContextDepth = CodeSynthesisContexts.size();
1327113286
}
1327213287
if (PragmaAttributeCurrentTargetDecl)
13273-
PrintPragmaAttributeInstantiationPoint();
13288+
PrintPragmaAttributeInstantiationPoint(DiagFunc);
1327413289
}
13290+
void PrintContextStack() { PrintContextStack(getDefaultDiagFunc()); }
1327513291
/// Prints the current instantiation stack through a series of
1327613292
/// notes.
13277-
void PrintInstantiationStack();
13293+
void PrintInstantiationStack(DiagFuncRef DiagFunc);
13294+
void PrintInstantiationStack() {
13295+
PrintInstantiationStack(getDefaultDiagFunc());
13296+
}
1327813297

1327913298
/// Determines whether we are currently in a context where
1328013299
/// template argument substitution failures are not considered

clang/lib/Sema/Sema.cpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1654,11 +1654,20 @@ void Sema::EmitDiagnostic(unsigned DiagID, const DiagnosticBuilder &DB) {
16541654
}
16551655

16561656
case DiagnosticIDs::SFINAE_Suppress:
1657+
if (DiagnosticsEngine::Level Level = getDiagnostics().getDiagnosticLevel(
1658+
DiagInfo.getID(), DiagInfo.getLocation());
1659+
Level == DiagnosticsEngine::Ignored)
1660+
return;
16571661
// Make a copy of this suppressed diagnostic and store it with the
16581662
// template-deduction information;
16591663
if (*Info) {
1660-
(*Info)->addSuppressedDiagnostic(DiagInfo.getLocation(),
1661-
PartialDiagnostic(DiagInfo, Context.getDiagAllocator()));
1664+
(*Info)->addSuppressedDiagnostic(
1665+
DiagInfo.getLocation(),
1666+
PartialDiagnostic(DiagInfo, Context.getDiagAllocator()));
1667+
if (!Diags.getDiagnosticIDs()->isNote(DiagID))
1668+
PrintContextStack([Info](SourceLocation Loc, PartialDiagnostic PD) {
1669+
(*Info)->addSuppressedDiagnostic(Loc, std::move(PD));
1670+
});
16621671
}
16631672

16641673
// Suppress this diagnostic.

clang/lib/Sema/SemaAttr.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1216,10 +1216,10 @@ void Sema::AddPragmaAttributes(Scope *S, Decl *D) {
12161216
}
12171217
}
12181218

1219-
void Sema::PrintPragmaAttributeInstantiationPoint() {
1219+
void Sema::PrintPragmaAttributeInstantiationPoint(DiagFuncRef DiagFunc) {
12201220
assert(PragmaAttributeCurrentTargetDecl && "Expected an active declaration");
1221-
Diags.Report(PragmaAttributeCurrentTargetDecl->getBeginLoc(),
1222-
diag::note_pragma_attribute_applied_decl_here);
1221+
DiagFunc(PragmaAttributeCurrentTargetDecl->getBeginLoc(),
1222+
PDiag(diag::note_pragma_attribute_applied_decl_here));
12231223
}
12241224

12251225
void Sema::DiagnosePrecisionLossInComplexDivision() {

clang/lib/Sema/SemaExpr.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -225,9 +225,10 @@ bool Sema::DiagnoseUseOfDecl(NamedDecl *D, ArrayRef<SourceLocation> Locs,
225225
// emit them now.
226226
auto Pos = SuppressedDiagnostics.find(D->getCanonicalDecl());
227227
if (Pos != SuppressedDiagnostics.end()) {
228-
for (const PartialDiagnosticAt &Suppressed : Pos->second)
229-
Diag(Suppressed.first, Suppressed.second);
230-
228+
for (const auto &[DiagLoc, PD] : Pos->second) {
229+
DiagnosticBuilder Builder(Diags.Report(DiagLoc, PD.getDiagID()));
230+
PD.Emit(Builder);
231+
}
231232
// Clear out the list of suppressed diagnostics, so that we don't emit
232233
// them again for this specialization. However, we don't obsolete this
233234
// entry from the table, because we want to avoid ever emitting these

0 commit comments

Comments
 (0)