Skip to content

Commit f6ea38d

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 0caba6c commit f6ea38d

18 files changed

+209
-161
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,9 @@ Bug Fixes to Attribute Support
128128
Bug Fixes to C++ Support
129129
^^^^^^^^^^^^^^^^^^^^^^^^
130130

131+
- Clang now prints the correct instantiation context for diagnostics suppressed
132+
by template argument deduction.
133+
131134
Bug Fixes to AST Handling
132135
^^^^^^^^^^^^^^^^^^^^^^^^^
133136

clang/include/clang/Sema/Sema.h

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1909,7 +1909,19 @@ 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+
DiagnosticBuilder Builder(Diags.Report(Loc, PD.getDiagID()));
1917+
PD.Emit(Builder);
1918+
};
1919+
}
1920+
1921+
void PrintPragmaAttributeInstantiationPoint(DiagFuncRef DiagFunc);
1922+
void PrintPragmaAttributeInstantiationPoint() {
1923+
PrintPragmaAttributeInstantiationPoint(getDefaultDiagFunc());
1924+
}
19131925

19141926
void DiagnoseUnterminatedPragmaAttribute();
19151927

@@ -13260,18 +13272,22 @@ class Sema final : public SemaBase {
1326013272
void pushCodeSynthesisContext(CodeSynthesisContext Ctx);
1326113273
void popCodeSynthesisContext();
1326213274

13263-
void PrintContextStack() {
13275+
void PrintContextStack(DiagFuncRef DiagFunc) {
1326413276
if (!CodeSynthesisContexts.empty() &&
1326513277
CodeSynthesisContexts.size() != LastEmittedCodeSynthesisContextDepth) {
13266-
PrintInstantiationStack();
13278+
PrintInstantiationStack(DiagFunc);
1326713279
LastEmittedCodeSynthesisContextDepth = CodeSynthesisContexts.size();
1326813280
}
1326913281
if (PragmaAttributeCurrentTargetDecl)
13270-
PrintPragmaAttributeInstantiationPoint();
13282+
PrintPragmaAttributeInstantiationPoint(DiagFunc);
1327113283
}
13284+
void PrintContextStack() { PrintContextStack(getDefaultDiagFunc()); }
1327213285
/// Prints the current instantiation stack through a series of
1327313286
/// notes.
13274-
void PrintInstantiationStack();
13287+
void PrintInstantiationStack(DiagFuncRef DiagFunc);
13288+
void PrintInstantiationStack() {
13289+
PrintInstantiationStack(getDefaultDiagFunc());
13290+
}
1327513291

1327613292
/// Determines whether we are currently in a context where
1327713293
/// 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
@@ -1217,10 +1217,10 @@ void Sema::AddPragmaAttributes(Scope *S, Decl *D) {
12171217
}
12181218
}
12191219

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

12261226
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)