Skip to content

Commit

Permalink
[clang] print correct context for diagnostics suppressed by deduction
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
mizvekov committed Feb 3, 2025
1 parent 0caba6c commit f6ea38d
Show file tree
Hide file tree
Showing 18 changed files with 209 additions and 161 deletions.
3 changes: 3 additions & 0 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,9 @@ Bug Fixes to Attribute Support
Bug Fixes to C++ Support
^^^^^^^^^^^^^^^^^^^^^^^^

- Clang now prints the correct instantiation context for diagnostics suppressed
by template argument deduction.

Bug Fixes to AST Handling
^^^^^^^^^^^^^^^^^^^^^^^^^

Expand Down
26 changes: 21 additions & 5 deletions clang/include/clang/Sema/Sema.h
Original file line number Diff line number Diff line change
Expand Up @@ -1909,7 +1909,19 @@ class Sema final : public SemaBase {
/// '\#pragma clang attribute push' directives to the given declaration.
void AddPragmaAttributes(Scope *S, Decl *D);

void PrintPragmaAttributeInstantiationPoint();
using DiagFuncRef =
llvm::function_ref<void(SourceLocation, PartialDiagnostic)>;
auto getDefaultDiagFunc() {
return [this](SourceLocation Loc, PartialDiagnostic PD) {
DiagnosticBuilder Builder(Diags.Report(Loc, PD.getDiagID()));
PD.Emit(Builder);
};
}

void PrintPragmaAttributeInstantiationPoint(DiagFuncRef DiagFunc);
void PrintPragmaAttributeInstantiationPoint() {
PrintPragmaAttributeInstantiationPoint(getDefaultDiagFunc());
}

void DiagnoseUnterminatedPragmaAttribute();

Expand Down Expand Up @@ -13260,18 +13272,22 @@ class Sema final : public SemaBase {
void pushCodeSynthesisContext(CodeSynthesisContext Ctx);
void popCodeSynthesisContext();

void PrintContextStack() {
void PrintContextStack(DiagFuncRef DiagFunc) {
if (!CodeSynthesisContexts.empty() &&
CodeSynthesisContexts.size() != LastEmittedCodeSynthesisContextDepth) {
PrintInstantiationStack();
PrintInstantiationStack(DiagFunc);
LastEmittedCodeSynthesisContextDepth = CodeSynthesisContexts.size();
}
if (PragmaAttributeCurrentTargetDecl)
PrintPragmaAttributeInstantiationPoint();
PrintPragmaAttributeInstantiationPoint(DiagFunc);
}
void PrintContextStack() { PrintContextStack(getDefaultDiagFunc()); }
/// Prints the current instantiation stack through a series of
/// notes.
void PrintInstantiationStack();
void PrintInstantiationStack(DiagFuncRef DiagFunc);
void PrintInstantiationStack() {
PrintInstantiationStack(getDefaultDiagFunc());
}

/// Determines whether we are currently in a context where
/// template argument substitution failures are not considered
Expand Down
13 changes: 11 additions & 2 deletions clang/lib/Sema/Sema.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1654,11 +1654,20 @@ void Sema::EmitDiagnostic(unsigned DiagID, const DiagnosticBuilder &DB) {
}

case DiagnosticIDs::SFINAE_Suppress:
if (DiagnosticsEngine::Level Level = getDiagnostics().getDiagnosticLevel(
DiagInfo.getID(), DiagInfo.getLocation());
Level == DiagnosticsEngine::Ignored)
return;
// Make a copy of this suppressed diagnostic and store it with the
// template-deduction information;
if (*Info) {
(*Info)->addSuppressedDiagnostic(DiagInfo.getLocation(),
PartialDiagnostic(DiagInfo, Context.getDiagAllocator()));
(*Info)->addSuppressedDiagnostic(
DiagInfo.getLocation(),
PartialDiagnostic(DiagInfo, Context.getDiagAllocator()));
if (!Diags.getDiagnosticIDs()->isNote(DiagID))
PrintContextStack([Info](SourceLocation Loc, PartialDiagnostic PD) {
(*Info)->addSuppressedDiagnostic(Loc, std::move(PD));
});
}

// Suppress this diagnostic.
Expand Down
6 changes: 3 additions & 3 deletions clang/lib/Sema/SemaAttr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1217,10 +1217,10 @@ void Sema::AddPragmaAttributes(Scope *S, Decl *D) {
}
}

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

void Sema::DiagnosePrecisionLossInComplexDivision() {
Expand Down
7 changes: 4 additions & 3 deletions clang/lib/Sema/SemaExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -225,9 +225,10 @@ bool Sema::DiagnoseUseOfDecl(NamedDecl *D, ArrayRef<SourceLocation> Locs,
// emit them now.
auto Pos = SuppressedDiagnostics.find(D->getCanonicalDecl());
if (Pos != SuppressedDiagnostics.end()) {
for (const PartialDiagnosticAt &Suppressed : Pos->second)
Diag(Suppressed.first, Suppressed.second);

for (const auto &[DiagLoc, PD] : Pos->second) {
DiagnosticBuilder Builder(Diags.Report(DiagLoc, PD.getDiagID()));
PD.Emit(Builder);
}
// Clear out the list of suppressed diagnostics, so that we don't emit
// them again for this specialization. However, we don't obsolete this
// entry from the table, because we want to avoid ever emitting these
Expand Down
Loading

0 comments on commit f6ea38d

Please sign in to comment.