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 <mizve...@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@-1 {{template argument uses unnamed type}} // cxx98-note@#cwg62-unnamed {{unnamed type used in template argument was declared here}} + // cxx98-note@-3 {{while substituting explicitly-specified template arguments}} NoNameForLinkagePtr p2 = get<const NoNameForLinkagePtr>(); // cxx98-error@-1 {{template argument uses unnamed type}} // cxx98-note@#cwg62-unnamed {{unnamed type used in template argument was declared here}} + // cxx98-note@-3 {{while substituting explicitly-specified template arguments}} int n1 = take(noNameForLinkagePtr); // cxx98-error@-1 {{template argument uses unnamed type}} // cxx98-note@#cwg62-unnamed {{unnamed type used in template argument was declared here}} + // cxx98-note@-3 {{while substituting deduced template arguments}} X<Danger> x4; @@ -1058,8 +1061,10 @@ namespace cwg62 { // cwg62: 2.9 // cxx98-error@-1 {{template argument uses local type }} get<NoLinkage>(); // cxx98-error@-1 {{template argument uses local type }} + // cxx98-note@-2 {{while substituting explicitly-specified template arguments}} get<const NoLinkage>(); // cxx98-error@-1 {{template argument uses local type }} + // cxx98-note@-2 {{while substituting explicitly-specified template arguments}} X<void (*)(NoLinkage A::*)> c; // cxx98-error@-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@-1 {{template argument uses local type 'E'}} + // cxx98-note@-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@-2 {{unnamed type used in template argument was declared here}} -#endif +// expected-note@-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@-2 {{template argument uses unnamed type}} + // expected-note@-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@-2 {{template argument uses unnamed type}} + // expected-note@-3 {{while substituting deduced template arguments}} #endif &f1<__typeof__(e1)>); #if __cplusplus <= 199711L // expected-warning@-2 {{template argument uses unnamed type}} + // expected-note@-3 {{while substituting explicitly-specified template arguments}} #endif int (*fp1)(int, __typeof__(e2)) = f1; #if __cplusplus <= 199711L // expected-warning@-2 {{template argument uses unnamed type}} + // expected-note@-3 {{while substituting deduced template arguments}} #endif f1(e2); #if __cplusplus <= 199711L // expected-warning@-2 {{template argument uses unnamed type}} + // expected-note@-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@-2 {{declared here}} -#endif +// expected-note@-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@-2 {{template argument uses unnamed type}} + // expected-note@-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@-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@-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@-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@-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@-1 {{array comparison always evaluates to false}} + // expected-warning@-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@-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@-1 {{in instantiation of function template specialization 'PR20731::g<(lambda at {{.*}}>' requested here}} + // cxx03-note@-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@-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@-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@-3 {{non-type template argument referring to function 'f' with internal linkage}} - // expected-warning@-3 {{non-type template argument referring to function 'f' with internal linkage}} + // expected-note@-4 {{while substituting explicitly-specified template arguments}} + // expected-warning@-4 {{non-type template argument referring to function 'f' with internal linkage}} + // expected-note@-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@-2 {{template argument uses local type 'LocalStruct'}} + // expected-note@-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@-1 {{while substituting explicitly-specified template arguments}} } namespace PR9227 { _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits