aboutsummaryrefslogtreecommitdiff
path: root/clang/lib
diff options
context:
space:
mode:
authorMatheus Izvekov <mizvekov@gmail.com>2025-02-20 08:50:03 -0300
committerGitHub <noreply@github.com>2025-02-20 08:50:03 -0300
commit0948fc85aa99a8fd193d2d66a517e31b8b639f20 (patch)
tree5177a4c7348fd6f0fd5fc81b67fccf883752d709 /clang/lib
parentd7784a649e80d346ba57ccc39f5e2a3e2f7e0a51 (diff)
downloadllvm-0948fc85aa99a8fd193d2d66a517e31b8b639f20.zip
llvm-0948fc85aa99a8fd193d2d66a517e31b8b639f20.tar.gz
llvm-0948fc85aa99a8fd193d2d66a517e31b8b639f20.tar.bz2
[clang] print correct context for diagnostics suppressed by deduction (#125453)
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.
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/Sema/Sema.cpp13
-rw-r--r--clang/lib/Sema/SemaAttr.cpp7
-rw-r--r--clang/lib/Sema/SemaExpr.cpp7
-rw-r--r--clang/lib/Sema/SemaTemplateInstantiate.cpp271
4 files changed, 155 insertions, 143 deletions
diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp
index afd1d7a..145cda6 100644
--- a/clang/lib/Sema/Sema.cpp
+++ b/clang/lib/Sema/Sema.cpp
@@ -1655,11 +1655,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.
diff --git a/clang/lib/Sema/SemaAttr.cpp b/clang/lib/Sema/SemaAttr.cpp
index 37c0546..3c2b63a 100644
--- a/clang/lib/Sema/SemaAttr.cpp
+++ b/clang/lib/Sema/SemaAttr.cpp
@@ -1221,10 +1221,11 @@ void Sema::AddPragmaAttributes(Scope *S, Decl *D) {
}
}
-void Sema::PrintPragmaAttributeInstantiationPoint() {
+void Sema::PrintPragmaAttributeInstantiationPoint(
+ InstantiationContextDiagFuncRef 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() {
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index fad15bf9..16226f1 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -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
diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp
index 121da49..fcb7671 100644
--- a/clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -903,7 +903,7 @@ bool Sema::InstantiatingTemplate::CheckInstantiationDepth(
return true;
}
-void Sema::PrintInstantiationStack() {
+void Sema::PrintInstantiationStack(InstantiationContextDiagFuncRef DiagFunc) {
// Determine which template instantiations to skip, if any.
unsigned SkipStart = CodeSynthesisContexts.size(), SkipEnd = SkipStart;
unsigned Limit = Diags.getTemplateBacktraceLimit();
@@ -923,9 +923,9 @@ void Sema::PrintInstantiationStack() {
if (InstantiationIdx >= SkipStart && InstantiationIdx < SkipEnd) {
if (InstantiationIdx == SkipStart) {
// Note that we're skipping instantiations.
- Diags.Report(Active->PointOfInstantiation,
- diag::note_instantiation_contexts_suppressed)
- << unsigned(CodeSynthesisContexts.size() - Limit);
+ DiagFunc(Active->PointOfInstantiation,
+ PDiag(diag::note_instantiation_contexts_suppressed)
+ << unsigned(CodeSynthesisContexts.size() - Limit));
}
continue;
}
@@ -937,37 +937,34 @@ void Sema::PrintInstantiationStack() {
unsigned DiagID = diag::note_template_member_class_here;
if (isa<ClassTemplateSpecializationDecl>(Record))
DiagID = diag::note_template_class_instantiation_here;
- Diags.Report(Active->PointOfInstantiation, DiagID)
- << Record << Active->InstantiationRange;
+ DiagFunc(Active->PointOfInstantiation,
+ PDiag(DiagID) << Record << Active->InstantiationRange);
} else if (FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
unsigned DiagID;
if (Function->getPrimaryTemplate())
DiagID = diag::note_function_template_spec_here;
else
DiagID = diag::note_template_member_function_here;
- Diags.Report(Active->PointOfInstantiation, DiagID)
- << Function
- << Active->InstantiationRange;
+ DiagFunc(Active->PointOfInstantiation,
+ PDiag(DiagID) << Function << Active->InstantiationRange);
} else if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
- Diags.Report(Active->PointOfInstantiation,
- VD->isStaticDataMember()?
- diag::note_template_static_data_member_def_here
- : diag::note_template_variable_def_here)
- << VD
- << Active->InstantiationRange;
+ DiagFunc(Active->PointOfInstantiation,
+ PDiag(VD->isStaticDataMember()
+ ? diag::note_template_static_data_member_def_here
+ : diag::note_template_variable_def_here)
+ << VD << Active->InstantiationRange);
} else if (EnumDecl *ED = dyn_cast<EnumDecl>(D)) {
- Diags.Report(Active->PointOfInstantiation,
- diag::note_template_enum_def_here)
- << ED
- << Active->InstantiationRange;
+ DiagFunc(Active->PointOfInstantiation,
+ PDiag(diag::note_template_enum_def_here)
+ << ED << Active->InstantiationRange);
} else if (FieldDecl *FD = dyn_cast<FieldDecl>(D)) {
- Diags.Report(Active->PointOfInstantiation,
- diag::note_template_nsdmi_here)
- << FD << Active->InstantiationRange;
+ DiagFunc(Active->PointOfInstantiation,
+ PDiag(diag::note_template_nsdmi_here)
+ << FD << Active->InstantiationRange);
} else if (ClassTemplateDecl *CTD = dyn_cast<ClassTemplateDecl>(D)) {
- Diags.Report(Active->PointOfInstantiation,
- diag::note_template_class_instantiation_here)
- << CTD << Active->InstantiationRange;
+ DiagFunc(Active->PointOfInstantiation,
+ PDiag(diag::note_template_class_instantiation_here)
+ << CTD << Active->InstantiationRange);
}
break;
}
@@ -979,35 +976,35 @@ void Sema::PrintInstantiationStack() {
Template->printName(OS, getPrintingPolicy());
printTemplateArgumentList(OS, Active->template_arguments(),
getPrintingPolicy());
- Diags.Report(Active->PointOfInstantiation,
- diag::note_default_arg_instantiation_here)
- << OS.str()
- << Active->InstantiationRange;
+ DiagFunc(Active->PointOfInstantiation,
+ PDiag(diag::note_default_arg_instantiation_here)
+ << OS.str() << Active->InstantiationRange);
break;
}
case CodeSynthesisContext::ExplicitTemplateArgumentSubstitution: {
FunctionTemplateDecl *FnTmpl = cast<FunctionTemplateDecl>(Active->Entity);
- Diags.Report(Active->PointOfInstantiation,
- diag::note_explicit_template_arg_substitution_here)
- << FnTmpl
- << getTemplateArgumentBindingsText(FnTmpl->getTemplateParameters(),
- Active->TemplateArgs,
- Active->NumTemplateArgs)
- << Active->InstantiationRange;
+ DiagFunc(Active->PointOfInstantiation,
+ PDiag(diag::note_explicit_template_arg_substitution_here)
+ << FnTmpl
+ << getTemplateArgumentBindingsText(
+ FnTmpl->getTemplateParameters(), Active->TemplateArgs,
+ Active->NumTemplateArgs)
+ << Active->InstantiationRange);
break;
}
case CodeSynthesisContext::DeducedTemplateArgumentSubstitution: {
if (FunctionTemplateDecl *FnTmpl =
dyn_cast<FunctionTemplateDecl>(Active->Entity)) {
- Diags.Report(Active->PointOfInstantiation,
- diag::note_function_template_deduction_instantiation_here)
- << FnTmpl
- << getTemplateArgumentBindingsText(FnTmpl->getTemplateParameters(),
- Active->TemplateArgs,
- Active->NumTemplateArgs)
- << Active->InstantiationRange;
+ DiagFunc(
+ Active->PointOfInstantiation,
+ PDiag(diag::note_function_template_deduction_instantiation_here)
+ << FnTmpl
+ << getTemplateArgumentBindingsText(
+ FnTmpl->getTemplateParameters(), Active->TemplateArgs,
+ Active->NumTemplateArgs)
+ << Active->InstantiationRange);
} else {
bool IsVar = isa<VarTemplateDecl>(Active->Entity) ||
isa<VarTemplateSpecializationDecl>(Active->Entity);
@@ -1026,12 +1023,13 @@ void Sema::PrintInstantiationStack() {
llvm_unreachable("unexpected template kind");
}
- Diags.Report(Active->PointOfInstantiation,
- diag::note_deduced_template_arg_substitution_here)
- << IsVar << IsTemplate << cast<NamedDecl>(Active->Entity)
- << getTemplateArgumentBindingsText(Params, Active->TemplateArgs,
- Active->NumTemplateArgs)
- << Active->InstantiationRange;
+ DiagFunc(Active->PointOfInstantiation,
+ PDiag(diag::note_deduced_template_arg_substitution_here)
+ << IsVar << IsTemplate << cast<NamedDecl>(Active->Entity)
+ << getTemplateArgumentBindingsText(Params,
+ Active->TemplateArgs,
+ Active->NumTemplateArgs)
+ << Active->InstantiationRange);
}
break;
}
@@ -1045,10 +1043,9 @@ void Sema::PrintInstantiationStack() {
FD->printName(OS, getPrintingPolicy());
printTemplateArgumentList(OS, Active->template_arguments(),
getPrintingPolicy());
- Diags.Report(Active->PointOfInstantiation,
- diag::note_default_function_arg_instantiation_here)
- << OS.str()
- << Active->InstantiationRange;
+ DiagFunc(Active->PointOfInstantiation,
+ PDiag(diag::note_default_function_arg_instantiation_here)
+ << OS.str() << Active->InstantiationRange);
break;
}
@@ -1065,14 +1062,13 @@ void Sema::PrintInstantiationStack() {
TemplateParams =
cast<ClassTemplatePartialSpecializationDecl>(Active->Template)
->getTemplateParameters();
- Diags.Report(Active->PointOfInstantiation,
- diag::note_prior_template_arg_substitution)
- << isa<TemplateTemplateParmDecl>(Parm)
- << Name
- << getTemplateArgumentBindingsText(TemplateParams,
- Active->TemplateArgs,
- Active->NumTemplateArgs)
- << Active->InstantiationRange;
+ DiagFunc(Active->PointOfInstantiation,
+ PDiag(diag::note_prior_template_arg_substitution)
+ << isa<TemplateTemplateParmDecl>(Parm) << Name
+ << getTemplateArgumentBindingsText(TemplateParams,
+ Active->TemplateArgs,
+ Active->NumTemplateArgs)
+ << Active->InstantiationRange);
break;
}
@@ -1085,55 +1081,56 @@ void Sema::PrintInstantiationStack() {
cast<ClassTemplatePartialSpecializationDecl>(Active->Template)
->getTemplateParameters();
- Diags.Report(Active->PointOfInstantiation,
- diag::note_template_default_arg_checking)
- << getTemplateArgumentBindingsText(TemplateParams,
- Active->TemplateArgs,
- Active->NumTemplateArgs)
- << Active->InstantiationRange;
+ DiagFunc(Active->PointOfInstantiation,
+ PDiag(diag::note_template_default_arg_checking)
+ << getTemplateArgumentBindingsText(TemplateParams,
+ Active->TemplateArgs,
+ Active->NumTemplateArgs)
+ << Active->InstantiationRange);
break;
}
case CodeSynthesisContext::ExceptionSpecEvaluation:
- Diags.Report(Active->PointOfInstantiation,
- diag::note_evaluating_exception_spec_here)
- << cast<FunctionDecl>(Active->Entity);
+ DiagFunc(Active->PointOfInstantiation,
+ PDiag(diag::note_evaluating_exception_spec_here)
+ << cast<FunctionDecl>(Active->Entity));
break;
case CodeSynthesisContext::ExceptionSpecInstantiation:
- Diags.Report(Active->PointOfInstantiation,
- diag::note_template_exception_spec_instantiation_here)
- << cast<FunctionDecl>(Active->Entity)
- << Active->InstantiationRange;
+ DiagFunc(Active->PointOfInstantiation,
+ PDiag(diag::note_template_exception_spec_instantiation_here)
+ << cast<FunctionDecl>(Active->Entity)
+ << Active->InstantiationRange);
break;
case CodeSynthesisContext::RequirementInstantiation:
- Diags.Report(Active->PointOfInstantiation,
- diag::note_template_requirement_instantiation_here)
- << Active->InstantiationRange;
+ DiagFunc(Active->PointOfInstantiation,
+ PDiag(diag::note_template_requirement_instantiation_here)
+ << Active->InstantiationRange);
break;
case CodeSynthesisContext::RequirementParameterInstantiation:
- Diags.Report(Active->PointOfInstantiation,
- diag::note_template_requirement_params_instantiation_here)
- << Active->InstantiationRange;
+ DiagFunc(Active->PointOfInstantiation,
+ PDiag(diag::note_template_requirement_params_instantiation_here)
+ << Active->InstantiationRange);
break;
case CodeSynthesisContext::NestedRequirementConstraintsCheck:
- Diags.Report(Active->PointOfInstantiation,
- diag::note_nested_requirement_here)
- << Active->InstantiationRange;
+ DiagFunc(Active->PointOfInstantiation,
+ PDiag(diag::note_nested_requirement_here)
+ << Active->InstantiationRange);
break;
case CodeSynthesisContext::DeclaringSpecialMember:
- Diags.Report(Active->PointOfInstantiation,
- diag::note_in_declaration_of_implicit_special_member)
- << cast<CXXRecordDecl>(Active->Entity)
- << llvm::to_underlying(Active->SpecialMember);
+ DiagFunc(Active->PointOfInstantiation,
+ PDiag(diag::note_in_declaration_of_implicit_special_member)
+ << cast<CXXRecordDecl>(Active->Entity)
+ << llvm::to_underlying(Active->SpecialMember));
break;
case CodeSynthesisContext::DeclaringImplicitEqualityComparison:
- Diags.Report(Active->Entity->getLocation(),
- diag::note_in_declaration_of_implicit_equality_comparison);
+ DiagFunc(
+ Active->Entity->getLocation(),
+ PDiag(diag::note_in_declaration_of_implicit_equality_comparison));
break;
case CodeSynthesisContext::DefiningSynthesizedFunction: {
@@ -1144,60 +1141,62 @@ void Sema::PrintInstantiationStack() {
FD ? getDefaultedFunctionKind(FD) : DefaultedFunctionKind();
if (DFK.isSpecialMember()) {
auto *MD = cast<CXXMethodDecl>(FD);
- Diags.Report(Active->PointOfInstantiation,
- diag::note_member_synthesized_at)
- << MD->isExplicitlyDefaulted()
- << llvm::to_underlying(DFK.asSpecialMember())
- << Context.getTagDeclType(MD->getParent());
+ DiagFunc(Active->PointOfInstantiation,
+ PDiag(diag::note_member_synthesized_at)
+ << MD->isExplicitlyDefaulted()
+ << llvm::to_underlying(DFK.asSpecialMember())
+ << Context.getTagDeclType(MD->getParent()));
} else if (DFK.isComparison()) {
QualType RecordType = FD->getParamDecl(0)
->getType()
.getNonReferenceType()
.getUnqualifiedType();
- Diags.Report(Active->PointOfInstantiation,
- diag::note_comparison_synthesized_at)
- << (int)DFK.asComparison() << RecordType;
+ DiagFunc(Active->PointOfInstantiation,
+ PDiag(diag::note_comparison_synthesized_at)
+ << (int)DFK.asComparison() << RecordType);
}
break;
}
case CodeSynthesisContext::RewritingOperatorAsSpaceship:
- Diags.Report(Active->Entity->getLocation(),
- diag::note_rewriting_operator_as_spaceship);
+ DiagFunc(Active->Entity->getLocation(),
+ PDiag(diag::note_rewriting_operator_as_spaceship));
break;
case CodeSynthesisContext::InitializingStructuredBinding:
- Diags.Report(Active->PointOfInstantiation,
- diag::note_in_binding_decl_init)
- << cast<BindingDecl>(Active->Entity);
+ DiagFunc(Active->PointOfInstantiation,
+ PDiag(diag::note_in_binding_decl_init)
+ << cast<BindingDecl>(Active->Entity));
break;
case CodeSynthesisContext::MarkingClassDllexported:
- Diags.Report(Active->PointOfInstantiation,
- diag::note_due_to_dllexported_class)
- << cast<CXXRecordDecl>(Active->Entity) << !getLangOpts().CPlusPlus11;
+ DiagFunc(Active->PointOfInstantiation,
+ PDiag(diag::note_due_to_dllexported_class)
+ << cast<CXXRecordDecl>(Active->Entity)
+ << !getLangOpts().CPlusPlus11);
break;
case CodeSynthesisContext::BuildingBuiltinDumpStructCall:
- Diags.Report(Active->PointOfInstantiation,
- diag::note_building_builtin_dump_struct_call)
- << convertCallArgsToString(
- *this, llvm::ArrayRef(Active->CallArgs, Active->NumCallArgs));
+ DiagFunc(Active->PointOfInstantiation,
+ PDiag(diag::note_building_builtin_dump_struct_call)
+ << convertCallArgsToString(
+ *this, llvm::ArrayRef(Active->CallArgs,
+ Active->NumCallArgs)));
break;
case CodeSynthesisContext::Memoization:
break;
case CodeSynthesisContext::LambdaExpressionSubstitution:
- Diags.Report(Active->PointOfInstantiation,
- diag::note_lambda_substitution_here);
+ DiagFunc(Active->PointOfInstantiation,
+ PDiag(diag::note_lambda_substitution_here));
break;
case CodeSynthesisContext::ConstraintsCheck: {
unsigned DiagID = 0;
if (!Active->Entity) {
- Diags.Report(Active->PointOfInstantiation,
- diag::note_nested_requirement_here)
- << Active->InstantiationRange;
+ DiagFunc(Active->PointOfInstantiation,
+ PDiag(diag::note_nested_requirement_here)
+ << Active->InstantiationRange);
break;
}
if (isa<ConceptDecl>(Active->Entity))
@@ -1219,42 +1218,44 @@ void Sema::PrintInstantiationStack() {
printTemplateArgumentList(OS, Active->template_arguments(),
getPrintingPolicy());
}
- Diags.Report(Active->PointOfInstantiation, DiagID) << OS.str()
- << Active->InstantiationRange;
+ DiagFunc(Active->PointOfInstantiation,
+ PDiag(DiagID) << OS.str() << Active->InstantiationRange);
break;
}
case CodeSynthesisContext::ConstraintSubstitution:
- Diags.Report(Active->PointOfInstantiation,
- diag::note_constraint_substitution_here)
- << Active->InstantiationRange;
+ DiagFunc(Active->PointOfInstantiation,
+ PDiag(diag::note_constraint_substitution_here)
+ << Active->InstantiationRange);
break;
case CodeSynthesisContext::ConstraintNormalization:
- Diags.Report(Active->PointOfInstantiation,
- diag::note_constraint_normalization_here)
- << cast<NamedDecl>(Active->Entity) << Active->InstantiationRange;
+ DiagFunc(Active->PointOfInstantiation,
+ PDiag(diag::note_constraint_normalization_here)
+ << cast<NamedDecl>(Active->Entity)
+ << Active->InstantiationRange);
break;
case CodeSynthesisContext::ParameterMappingSubstitution:
- Diags.Report(Active->PointOfInstantiation,
- diag::note_parameter_mapping_substitution_here)
- << Active->InstantiationRange;
+ DiagFunc(Active->PointOfInstantiation,
+ PDiag(diag::note_parameter_mapping_substitution_here)
+ << Active->InstantiationRange);
break;
case CodeSynthesisContext::BuildingDeductionGuides:
- Diags.Report(Active->PointOfInstantiation,
- diag::note_building_deduction_guide_here);
+ DiagFunc(Active->PointOfInstantiation,
+ PDiag(diag::note_building_deduction_guide_here));
break;
case CodeSynthesisContext::TypeAliasTemplateInstantiation:
- Diags.Report(Active->PointOfInstantiation,
- diag::note_template_type_alias_instantiation_here)
- << cast<TypeAliasTemplateDecl>(Active->Entity)
- << Active->InstantiationRange;
+ DiagFunc(Active->PointOfInstantiation,
+ PDiag(diag::note_template_type_alias_instantiation_here)
+ << cast<TypeAliasTemplateDecl>(Active->Entity)
+ << Active->InstantiationRange);
break;
case CodeSynthesisContext::PartialOrderingTTP:
- Diags.Report(Active->PointOfInstantiation,
- diag::note_template_arg_template_params_mismatch);
+ DiagFunc(Active->PointOfInstantiation,
+ PDiag(diag::note_template_arg_template_params_mismatch));
if (SourceLocation ParamLoc = Active->Entity->getLocation();
ParamLoc.isValid())
- Diags.Report(ParamLoc, diag::note_template_prev_declaration)
- << /*isTemplateTemplateParam=*/true << Active->InstantiationRange;
+ DiagFunc(ParamLoc, PDiag(diag::note_template_prev_declaration)
+ << /*isTemplateTemplateParam=*/true
+ << Active->InstantiationRange);
break;
}
}