[clang] [clang] print correct context for diagnostics suppressed by deduction (PR #125453)
Matheus Izvekov via cfe-commits
cfe-commits at lists.llvm.org
Wed Feb 5 13:24:11 PST 2025
https://github.com/mizvekov updated https://github.com/llvm/llvm-project/pull/125453
>From adde9f1f8eabe4d98ba09fd978f8d152a9865347 Mon Sep 17 00:00:00 2001
From: Matheus Izvekov <mizvekov at gmail.com>
Date: Sun, 2 Feb 2025 23:47:15 -0300
Subject: [PATCH] [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.
---
clang/docs/ReleaseNotes.rst | 2 +
clang/include/clang/Sema/Sema.h | 26 +-
clang/lib/Sema/Sema.cpp | 13 +-
clang/lib/Sema/SemaAttr.cpp | 6 +-
clang/lib/Sema/SemaExpr.cpp | 7 +-
clang/lib/Sema/SemaTemplateInstantiate.cpp | 271 +++++++++---------
clang/test/CXX/drs/cwg0xx.cpp | 5 +
clang/test/CXX/drs/cwg4xx.cpp | 3 +-
.../CXX/temp/temp.arg/temp.arg.type/p2.cpp | 9 +-
clang/test/SemaCXX/anonymous-struct.cpp | 5 +-
clang/test/SemaCXX/bool-increment-SFINAE.cpp | 4 +-
clang/test/SemaCXX/cxx98-compat-flags.cpp | 2 +
clang/test/SemaCXX/cxx98-compat.cpp | 2 +
clang/test/SemaCXX/deprecated.cpp | 4 +-
clang/test/SemaCXX/lambda-expressions.cpp | 2 +
clang/test/SemaCXX/undefined-internal.cpp | 6 +-
clang/test/SemaTemplate/recovery-crash.cpp | 1 +
clang/test/SemaTemplate/temp_arg_nontype.cpp | 1 +
18 files changed, 208 insertions(+), 161 deletions(-)
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 21c1ff25d2862ba..dfce173d414ebb2 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -146,6 +146,8 @@ Bug Fixes to C++ Support
^^^^^^^^^^^^^^^^^^^^^^^^
- Clang is now better at keeping track of friend function template instance contexts. (#GH55509)
+- Clang now prints the correct instantiation context for diagnostics suppressed
+ by template argument deduction.
Bug Fixes to AST Handling
^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 1870d1271c556cb..c0e01c817cf100b 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -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();
@@ -13263,18 +13275,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
diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp
index 15c18f9a4525b22..f3f7111a3a200f3 100644
--- a/clang/lib/Sema/Sema.cpp
+++ b/clang/lib/Sema/Sema.cpp
@@ -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.
diff --git a/clang/lib/Sema/SemaAttr.cpp b/clang/lib/Sema/SemaAttr.cpp
index defdda17c32dedb..e9a6c6b52b9bae8 100644
--- a/clang/lib/Sema/SemaAttr.cpp
+++ b/clang/lib/Sema/SemaAttr.cpp
@@ -1216,10 +1216,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() {
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 3cd4010740d1944..46e2ebfcf54e605 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 d9a47ca3daa20c5..cccf2095816db14 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(DiagFuncRef 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;
}
}
diff --git a/clang/test/CXX/drs/cwg0xx.cpp b/clang/test/CXX/drs/cwg0xx.cpp
index 44a0eb520af2216..282e71bbf3bdaab 100644
--- a/clang/test/CXX/drs/cwg0xx.cpp
+++ b/clang/test/CXX/drs/cwg0xx.cpp
@@ -1041,12 +1041,15 @@ namespace cwg62 { // cwg62: 2.9
NoNameForLinkagePtr p1 = get<NoNameForLinkagePtr>();
// cxx98-error at -1 {{template argument uses unnamed type}}
// cxx98-note@#cwg62-unnamed {{unnamed type used in template argument was declared here}}
+ // cxx98-note at -3 {{while substituting explicitly-specified template arguments}}
NoNameForLinkagePtr p2 = get<const NoNameForLinkagePtr>();
// cxx98-error at -1 {{template argument uses unnamed type}}
// cxx98-note@#cwg62-unnamed {{unnamed type used in template argument was declared here}}
+ // cxx98-note at -3 {{while substituting explicitly-specified template arguments}}
int n1 = take(noNameForLinkagePtr);
// cxx98-error at -1 {{template argument uses unnamed type}}
// cxx98-note@#cwg62-unnamed {{unnamed type used in template argument was declared here}}
+ // cxx98-note at -3 {{while substituting deduced template arguments}}
X<Danger> x4;
@@ -1058,8 +1061,10 @@ namespace cwg62 { // cwg62: 2.9
// cxx98-error at -1 {{template argument uses local type }}
get<NoLinkage>();
// cxx98-error at -1 {{template argument uses local type }}
+ // cxx98-note at -2 {{while substituting explicitly-specified template arguments}}
get<const NoLinkage>();
// cxx98-error at -1 {{template argument uses local type }}
+ // cxx98-note at -2 {{while substituting explicitly-specified template arguments}}
X<void (*)(NoLinkage A::*)> c;
// cxx98-error at -1 {{template argument uses local type }}
X<int NoLinkage::*> d;
diff --git a/clang/test/CXX/drs/cwg4xx.cpp b/clang/test/CXX/drs/cwg4xx.cpp
index bcaf7db04ad3b5d..0debc104ac45b82 100644
--- a/clang/test/CXX/drs/cwg4xx.cpp
+++ b/clang/test/CXX/drs/cwg4xx.cpp
@@ -20,7 +20,7 @@ namespace cwg400 { // cwg400: 2.7
struct A { int a; struct a {}; }; // #cwg400-A
struct B { int a; struct a {}; }; // #cwg400-B
struct C : A, B { using A::a; struct a b; };
- struct D : A, B {
+ struct D : A, B {
using A::a;
// FIXME: we should issue a single diagnostic
using B::a; // #cwg400-using-B-a
@@ -1386,6 +1386,7 @@ namespace cwg488 { // cwg488: 2.9 c++11
enum E { e };
f(e);
// cxx98-error at -1 {{template argument uses local type 'E'}}
+ // cxx98-note at -2 {{while substituting deduced template arguments}}
}
} // namespace cwg488
diff --git a/clang/test/CXX/temp/temp.arg/temp.arg.type/p2.cpp b/clang/test/CXX/temp/temp.arg/temp.arg.type/p2.cpp
index 1e314da3139903e..650f8585b115a87 100644
--- a/clang/test/CXX/temp/temp.arg/temp.arg.type/p2.cpp
+++ b/clang/test/CXX/temp/temp.arg/temp.arg.type/p2.cpp
@@ -15,14 +15,13 @@ B<function> b; // expected-note{{instantiation of}}
template <typename T> int f0(void *, const T&); // expected-note{{candidate template ignored: substitution failure}}
enum {e};
-#if __cplusplus <= 199711L
-// expected-note at -2 {{unnamed type used in template argument was declared here}}
-#endif
+// expected-note at -1 {{unnamed type used in template argument was declared here}}
void test_f0(int n) { // #here
int i = f0(0, e);
#if __cplusplus <= 199711L
// expected-warning at -2 {{template argument uses unnamed type}}
+ // expected-note at -3 {{while substituting deduced template arguments}}
#endif
int vla[n]; // expected-warning {{variable length arrays in C++ are a Clang extension}}
@@ -59,21 +58,25 @@ namespace N0 {
f0(
#if __cplusplus <= 199711L
// expected-warning at -2 {{template argument uses unnamed type}}
+ // expected-note at -3 {{while substituting deduced template arguments}}
#endif
&f1<__typeof__(e1)>);
#if __cplusplus <= 199711L
// expected-warning at -2 {{template argument uses unnamed type}}
+ // expected-note at -3 {{while substituting explicitly-specified template arguments}}
#endif
int (*fp1)(int, __typeof__(e2)) = f1;
#if __cplusplus <= 199711L
// expected-warning at -2 {{template argument uses unnamed type}}
+ // expected-note at -3 {{while substituting deduced template arguments}}
#endif
f1(e2);
#if __cplusplus <= 199711L
// expected-warning at -2 {{template argument uses unnamed type}}
+ // expected-note at -3 {{while substituting deduced template arguments}}
#endif
f1(e2);
diff --git a/clang/test/SemaCXX/anonymous-struct.cpp b/clang/test/SemaCXX/anonymous-struct.cpp
index e1db98d2b2f5079..75309821998eba1 100644
--- a/clang/test/SemaCXX/anonymous-struct.cpp
+++ b/clang/test/SemaCXX/anonymous-struct.cpp
@@ -29,14 +29,13 @@ struct E {
template <class T> void foo(T);
typedef struct { // expected-error {{anonymous non-C-compatible type given name for linkage purposes by typedef declaration after its linkage was computed; add a tag name here to establish linkage prior to definition}}
-#if __cplusplus <= 199711L
-// expected-note at -2 {{declared here}}
-#endif
+// expected-note at -1 {{unnamed type used in template argument was declared here}}
void test() { // expected-note {{type is not C-compatible due to this member declaration}}
foo(this);
#if __cplusplus <= 199711L
// expected-warning at -2 {{template argument uses unnamed type}}
+ // expected-note at -3 {{while substituting deduced template arguments}}
#endif
}
} A; // expected-note {{type is given name 'A' for linkage purposes by this typedef declaration}}
diff --git a/clang/test/SemaCXX/bool-increment-SFINAE.cpp b/clang/test/SemaCXX/bool-increment-SFINAE.cpp
index d3889293fc0b642..3a465fa5a3d5a22 100644
--- a/clang/test/SemaCXX/bool-increment-SFINAE.cpp
+++ b/clang/test/SemaCXX/bool-increment-SFINAE.cpp
@@ -7,7 +7,7 @@
template<class T> auto f(T t) -> decltype(++t); // precxx17-warning {{incrementing expression of type bool is deprecated}}
auto f(...) -> void;
-void g() { f(true); }
+void g() { f(true); } // precxx17-note {{while substituting deduced template arguments}}
#ifdef FAILED_CXX17
@@ -30,7 +30,7 @@ void f() {
int main() {
f<bool>(); // cxx20-note {{in instantiation of function template specialization 'f<bool>' requested here}}
- static_assert(!can_increment<bool>);
+ static_assert(!can_increment<bool>);
return 0;
}
diff --git a/clang/test/SemaCXX/cxx98-compat-flags.cpp b/clang/test/SemaCXX/cxx98-compat-flags.cpp
index 1fdb50c7fb2878f..6ffb3a5884d17cc 100644
--- a/clang/test/SemaCXX/cxx98-compat-flags.cpp
+++ b/clang/test/SemaCXX/cxx98-compat-flags.cpp
@@ -5,9 +5,11 @@ template<typename T> int TemplateFn(T) { return 0; }
void LocalTemplateArg() {
struct S {};
TemplateFn(S()); // expected-warning {{local type 'S' as template argument is incompatible with C++98}}
+ // expected-note at -1 {{while substituting deduced template arguments}}
}
struct {} obj_of_unnamed_type; // expected-note {{here}}
int UnnamedTemplateArg = TemplateFn(obj_of_unnamed_type); // expected-warning {{unnamed type as template argument is incompatible with C++98}}
+ // expected-note at -1 {{while substituting deduced template arguments}}
namespace CopyCtorIssues {
struct Private {
diff --git a/clang/test/SemaCXX/cxx98-compat.cpp b/clang/test/SemaCXX/cxx98-compat.cpp
index 28547d42c64902d..d31d95a9995f19f 100644
--- a/clang/test/SemaCXX/cxx98-compat.cpp
+++ b/clang/test/SemaCXX/cxx98-compat.cpp
@@ -177,9 +177,11 @@ template<typename T> int TemplateFn(T) { return 0; }
void LocalTemplateArg() {
struct S {};
TemplateFn(S()); // expected-warning {{local type 'S' as template argument is incompatible with C++98}}
+ // expected-note at -1 {{while substituting deduced template arguments}}
}
struct {} obj_of_unnamed_type; // expected-note {{here}}
int UnnamedTemplateArg = TemplateFn(obj_of_unnamed_type); // expected-warning {{unnamed type as template argument is incompatible with C++98}}
+ // expected-note at -1 {{while substituting deduced template arguments}}
// FIXME: We do not implement C++98 compatibility warnings for the C++17
// template argument evaluation rules.
diff --git a/clang/test/SemaCXX/deprecated.cpp b/clang/test/SemaCXX/deprecated.cpp
index 4282239af81b4c9..a24b40d8e622a8b 100644
--- a/clang/test/SemaCXX/deprecated.cpp
+++ b/clang/test/SemaCXX/deprecated.cpp
@@ -216,7 +216,7 @@ namespace DeprecatedVolatile {
#endif
template<typename T> T f(T v); // cxx20-warning 2{{deprecated}}
- int use_f = f<volatile int>(0); // FIXME: Missing "in instantiation of" note.
+ int use_f = f<volatile int>(0); // cxx20-note {{while substituting deduced template arguments}}
// OK, only the built-in operators are deprecated.
struct UDT {
@@ -247,7 +247,7 @@ namespace ArithConv {
namespace ArrayComp {
int arr1[3], arr2[4];
bool b1 = arr1 == arr2; // not-cxx20-warning {{comparison between two arrays compare their addresses}} cxx20-warning {{comparison between two arrays is deprecated}}
- // expected-warning at -1 {{array comparison always evaluates to false}}
+ // expected-warning at -1 {{array comparison always evaluates to false}}
bool b2 = arr1 < arr2; // not-cxx20-warning {{comparison between two arrays compare their addresses}} cxx20-warning {{comparison between two arrays is deprecated}}
// expected-warning at -1 {{array comparison always evaluates to a constant}}
__attribute__((weak)) int arr3[3];
diff --git a/clang/test/SemaCXX/lambda-expressions.cpp b/clang/test/SemaCXX/lambda-expressions.cpp
index f3deb6ee3f4244f..2d2dde82a28e6b6 100644
--- a/clang/test/SemaCXX/lambda-expressions.cpp
+++ b/clang/test/SemaCXX/lambda-expressions.cpp
@@ -452,6 +452,7 @@ void g(F f) {
void f() {
g([] {}); // cxx03-warning {{template argument uses local type}}
// expected-note-re at -1 {{in instantiation of function template specialization 'PR20731::g<(lambda at {{.*}}>' requested here}}
+ // cxx03-note at -2 {{while substituting deduced template arguments}}
}
template <class _Rp> struct function {
@@ -503,6 +504,7 @@ namespace PR21857 {
};
template<typename Fn> fun<Fn> wrap(Fn fn); // cxx03-warning {{template argument uses unnamed type}}
auto x = wrap([](){}); // cxx03-warning {{template argument uses unnamed type}} cxx03-note 2 {{unnamed type used in template argument was declared here}}
+ // cxx03-note at -1 {{while substituting deduced template arguments into function template}}
}
namespace PR13987 {
diff --git a/clang/test/SemaCXX/undefined-internal.cpp b/clang/test/SemaCXX/undefined-internal.cpp
index 054e71b92f93d2f..9745f097c76b78c 100644
--- a/clang/test/SemaCXX/undefined-internal.cpp
+++ b/clang/test/SemaCXX/undefined-internal.cpp
@@ -133,7 +133,7 @@ namespace PR9323 {
}
void f(const Uncopyable&) {}
void test() {
- f(Uncopyable());
+ f(Uncopyable());
#if __cplusplus <= 199711L // C++03 or earlier modes
// expected-warning at -2 {{C++98 requires an accessible copy constructor}}
#else
@@ -209,7 +209,9 @@ namespace OverloadUse {
t<f>(&n, &n); // expected-note {{used here}}
#if __cplusplus < 201103L
// expected-warning at -3 {{non-type template argument referring to function 'f' with internal linkage}}
- // expected-warning at -3 {{non-type template argument referring to function 'f' with internal linkage}}
+ // expected-note at -4 {{while substituting explicitly-specified template arguments}}
+ // expected-warning at -4 {{non-type template argument referring to function 'f' with internal linkage}}
+ // expected-note at -5 {{while substituting explicitly-specified template arguments}}
#endif
}
}
diff --git a/clang/test/SemaTemplate/recovery-crash.cpp b/clang/test/SemaTemplate/recovery-crash.cpp
index 88e989aeb406493..ac8053da101ab34 100644
--- a/clang/test/SemaTemplate/recovery-crash.cpp
+++ b/clang/test/SemaTemplate/recovery-crash.cpp
@@ -32,6 +32,7 @@ namespace PR16225 {
f<LocalStruct>();
#if __cplusplus <= 199711L
// expected-warning at -2 {{template argument uses local type 'LocalStruct'}}
+ // expected-note at -3 {{while substituting explicitly-specified template arguments}}
#endif
struct LocalStruct2 : UnknownBase<C> { }; // expected-error {{no template named 'UnknownBase'}}
}
diff --git a/clang/test/SemaTemplate/temp_arg_nontype.cpp b/clang/test/SemaTemplate/temp_arg_nontype.cpp
index 8b270b22a12b461..2a1c059df002ea3 100644
--- a/clang/test/SemaTemplate/temp_arg_nontype.cpp
+++ b/clang/test/SemaTemplate/temp_arg_nontype.cpp
@@ -255,6 +255,7 @@ namespace test8 {
namespace PR8372 {
template <int I> void foo() { } // expected-note{{template parameter is declared here}}
void bar() { foo <0x80000000> (); } // expected-warning{{non-type template argument value '2147483648' truncated to '-2147483648' for template parameter of type 'int'}}
+ // expected-note at -1 {{while substituting explicitly-specified template arguments}}
}
namespace PR9227 {
More information about the cfe-commits
mailing list