diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 8be1ea2fb0145..70c3b062d9771 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -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 ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 472a0e25adc97..7d01dc1aa4c00 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; + 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(); @@ -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 diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp index 9507d7602aa40..33e2bd1e03051 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 6907fa91e28c2..b66c7d3024adc 100644 --- a/clang/lib/Sema/SemaAttr.cpp +++ b/clang/lib/Sema/SemaAttr.cpp @@ -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() { diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index ba4aaa94b90ff..1d693333fef58 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -225,9 +225,10 @@ bool Sema::DiagnoseUseOfDecl(NamedDecl *D, ArrayRef 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 dc3bfa97eff39..dd832d0dd709b 100644 --- a/clang/lib/Sema/SemaTemplateInstantiate.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -904,7 +904,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(); @@ -924,9 +924,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; } @@ -938,37 +938,34 @@ void Sema::PrintInstantiationStack() { unsigned DiagID = diag::note_template_member_class_here; if (isa(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(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(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(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(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(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; } @@ -980,35 +977,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(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(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(Active->Entity) || isa(Active->Entity); @@ -1027,12 +1024,13 @@ void Sema::PrintInstantiationStack() { llvm_unreachable("unexpected template kind"); } - Diags.Report(Active->PointOfInstantiation, - diag::note_deduced_template_arg_substitution_here) - << IsVar << IsTemplate << cast(Active->Entity) - << getTemplateArgumentBindingsText(Params, Active->TemplateArgs, - Active->NumTemplateArgs) - << Active->InstantiationRange; + DiagFunc(Active->PointOfInstantiation, + PDiag(diag::note_deduced_template_arg_substitution_here) + << IsVar << IsTemplate << cast(Active->Entity) + << getTemplateArgumentBindingsText(Params, + Active->TemplateArgs, + Active->NumTemplateArgs) + << Active->InstantiationRange); } break; } @@ -1046,10 +1044,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; } @@ -1066,14 +1063,13 @@ void Sema::PrintInstantiationStack() { TemplateParams = cast(Active->Template) ->getTemplateParameters(); - Diags.Report(Active->PointOfInstantiation, - diag::note_prior_template_arg_substitution) - << isa(Parm) - << Name - << getTemplateArgumentBindingsText(TemplateParams, - Active->TemplateArgs, - Active->NumTemplateArgs) - << Active->InstantiationRange; + DiagFunc(Active->PointOfInstantiation, + PDiag(diag::note_prior_template_arg_substitution) + << isa(Parm) << Name + << getTemplateArgumentBindingsText(TemplateParams, + Active->TemplateArgs, + Active->NumTemplateArgs) + << Active->InstantiationRange); break; } @@ -1086,55 +1082,56 @@ void Sema::PrintInstantiationStack() { cast(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(Active->Entity); + DiagFunc(Active->PointOfInstantiation, + PDiag(diag::note_evaluating_exception_spec_here) + << cast(Active->Entity)); break; case CodeSynthesisContext::ExceptionSpecInstantiation: - Diags.Report(Active->PointOfInstantiation, - diag::note_template_exception_spec_instantiation_here) - << cast(Active->Entity) - << Active->InstantiationRange; + DiagFunc(Active->PointOfInstantiation, + PDiag(diag::note_template_exception_spec_instantiation_here) + << cast(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(Active->Entity) - << llvm::to_underlying(Active->SpecialMember); + DiagFunc(Active->PointOfInstantiation, + PDiag(diag::note_in_declaration_of_implicit_special_member) + << cast(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: { @@ -1145,60 +1142,62 @@ void Sema::PrintInstantiationStack() { FD ? getDefaultedFunctionKind(FD) : DefaultedFunctionKind(); if (DFK.isSpecialMember()) { auto *MD = cast(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(Active->Entity); + DiagFunc(Active->PointOfInstantiation, + PDiag(diag::note_in_binding_decl_init) + << cast(Active->Entity)); break; case CodeSynthesisContext::MarkingClassDllexported: - Diags.Report(Active->PointOfInstantiation, - diag::note_due_to_dllexported_class) - << cast(Active->Entity) << !getLangOpts().CPlusPlus11; + DiagFunc(Active->PointOfInstantiation, + PDiag(diag::note_due_to_dllexported_class) + << cast(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(Active->Entity)) @@ -1220,42 +1219,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(Active->Entity) << Active->InstantiationRange; + DiagFunc(Active->PointOfInstantiation, + PDiag(diag::note_constraint_normalization_here) + << cast(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(Active->Entity) - << Active->InstantiationRange; + DiagFunc(Active->PointOfInstantiation, + PDiag(diag::note_template_type_alias_instantiation_here) + << cast(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 44a0eb520af22..3efe9f87af7fa 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(); // 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(); // 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 x4; @@ -1058,8 +1061,10 @@ namespace cwg62 { // cwg62: 2.9 // cxx98-error@-1 {{template argument uses local type }} get(); // cxx98-error@-1 {{template argument uses local type }} + // cxx98-note@-2 {{while substituting explicitly-specified template arguments}} get(); // cxx98-error@-1 {{template argument uses local type }} + // cxx98-note@-2 {{while substituting explicitly-specified template arguments}} X c; // cxx98-error@-1 {{template argument uses local type }} X d; diff --git a/clang/test/CXX/drs/cwg4xx.cpp b/clang/test/CXX/drs/cwg4xx.cpp index bcaf7db04ad3b..65d9af42e814e 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 1e314da313990..650f8585b115a 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 b; // expected-note{{instantiation of}} template 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 e1db98d2b2f50..75309821998eb 100644 --- a/clang/test/SemaCXX/anonymous-struct.cpp +++ b/clang/test/SemaCXX/anonymous-struct.cpp @@ -29,14 +29,13 @@ struct E { template 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 d3889293fc0b6..3a465fa5a3d5a 100644 --- a/clang/test/SemaCXX/bool-increment-SFINAE.cpp +++ b/clang/test/SemaCXX/bool-increment-SFINAE.cpp @@ -7,7 +7,7 @@ template 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(); // cxx20-note {{in instantiation of function template specialization 'f' requested here}} - static_assert(!can_increment); + static_assert(!can_increment); return 0; } diff --git a/clang/test/SemaCXX/cxx98-compat-flags.cpp b/clang/test/SemaCXX/cxx98-compat-flags.cpp index 1fdb50c7fb287..6ffb3a5884d17 100644 --- a/clang/test/SemaCXX/cxx98-compat-flags.cpp +++ b/clang/test/SemaCXX/cxx98-compat-flags.cpp @@ -5,9 +5,11 @@ template 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 28547d42c6490..d31d95a9995f1 100644 --- a/clang/test/SemaCXX/cxx98-compat.cpp +++ b/clang/test/SemaCXX/cxx98-compat.cpp @@ -177,9 +177,11 @@ template 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 4282239af81b4..a24b40d8e622a 100644 --- a/clang/test/SemaCXX/deprecated.cpp +++ b/clang/test/SemaCXX/deprecated.cpp @@ -216,7 +216,7 @@ namespace DeprecatedVolatile { #endif template T f(T v); // cxx20-warning 2{{deprecated}} - int use_f = f(0); // FIXME: Missing "in instantiation of" note. + int use_f = f(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 f3deb6ee3f424..2d2dde82a28e6 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 struct function { @@ -503,6 +504,7 @@ namespace PR21857 { }; template fun 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 054e71b92f93d..9745f097c76b7 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(&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 88e989aeb4064..ac8053da101ab 100644 --- a/clang/test/SemaTemplate/recovery-crash.cpp +++ b/clang/test/SemaTemplate/recovery-crash.cpp @@ -32,6 +32,7 @@ namespace PR16225 { f(); #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 { }; // 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 8b270b22a12b4..2a1c059df002e 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 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 {