diff options
104 files changed, 688 insertions, 578 deletions
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 98c889c..e942834 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -304,7 +304,11 @@ Improvements to Clang's diagnostics - Fixed false positives in ``-Waddress-of-packed-member`` diagnostics when potential misaligned members get processed before they can get discarded. (#GH144729) - +- Clang now more consistently adds a note pointing to the relevant template + parameter. Some diagnostics are reworded to better take advantage of this. +- Template Template Parameter diagnostics now stop referring to template + parameters as template arguments, in some circumstances, better hiding + from the users template template parameter partial ordering arcana. - Clang now emits dignostic with correct message in case of assigning to const reference captured in lambda. (#GH105647) - Fixed false positive in ``-Wmissing-noreturn`` diagnostic when it was requiring the usage of diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index dc4c6d3..79ef6dd 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -5358,19 +5358,14 @@ def err_template_linkage : Error<"templates must have C++ linkage">; def err_template_typedef : Error<"a typedef cannot be a template">; def err_template_unnamed_class : Error< "cannot declare a class template with no name">; -def err_template_param_list_different_arity : Error< - "%select{too few|too many}0 template parameters in template " - "%select{|template parameter }1redeclaration">; -def note_template_param_list_different_arity : Note< - "%select{too few|too many}0 template parameters in template template " - "argument">; +def err_template_param_list_different_arity + : Error<"%select{too few|too many}0 template parameters in template " + "%select{|template parameter }1redeclaration">; def note_template_prev_declaration : Note< "previous template %select{declaration|template parameter}0 is here">; -def err_template_param_different_kind : Error< - "template parameter has a different kind in template " - "%select{|template parameter }0redeclaration">; -def note_template_param_different_kind : Note< - "template parameter has a different kind in template argument">; +def err_template_param_different_kind + : Error<"template parameter has a different kind in template " + "%select{|template parameter }0redeclaration">; def err_invalid_decl_specifier_in_nontype_parm : Error< "invalid declaration specifier in template non-type parameter">; @@ -5379,8 +5374,6 @@ def err_template_nontype_parm_different_type : Error< "template non-type parameter has a different type %0 in template " "%select{|template parameter }1redeclaration">; -def note_template_nontype_parm_different_type : Note< - "template non-type parameter has a different type %0 in template argument">; def note_template_nontype_parm_prev_declaration : Note< "previous non-type template parameter with type %0 is here">; def err_template_nontype_parm_bad_type : Error< @@ -5454,10 +5447,17 @@ def err_template_missing_args : Error< "%select{class template|function template|variable template|alias template|" "template template parameter|concept|template}0 %1 requires template " "arguments">; -def err_template_arg_list_different_arity : Error< - "%select{too few|too many}0 template arguments for " - "%select{class template|function template|variable template|alias template|" - "template template parameter|concept|template}1 %2">; +def err_template_param_missing_arg + : Error<"missing template argument for template parameter">; +def err_template_template_param_missing_param + : Error<"no template parameter in this template template parameter " + "corresponds to non-defaulted template parameter of argument " + "template">; +def err_template_too_many_args + : Error<"too many template arguments for " + "%select{class template|function template|variable template|alias " + "template|" + "template template parameter|concept|template}0 %1">; def note_template_decl_here : Note<"template is declared here">; def note_template_decl_external : Note< "template declaration from hidden source: %0">; @@ -5500,12 +5500,9 @@ def err_template_arg_not_valid_template def note_template_arg_refers_to_template_here : Note<"template argument refers to a %select{function template|class " "template|variable template|concept}0 %1, here">; -def err_template_arg_template_params_mismatch : Error< - "template template argument has different template parameters than its " - "corresponding template template parameter">; -def note_template_arg_template_params_mismatch : Note< - "template template argument has different template parameters than its " - "corresponding template template parameter">; +def note_template_arg_template_params_mismatch + : Note<"template template argument is incompatible with its " + "corresponding template template parameter">; def err_non_deduced_mismatch : Error< "could not match %diff{$ against $|types}0,1">; def err_inconsistent_deduction : Error< @@ -5770,8 +5767,10 @@ def err_template_recursion_depth_exceeded : Error< def err_constraint_depends_on_self : Error<"satisfaction of constraint %0 depends on itself">, NoSFINAE; -def note_template_recursion_depth : Note< - "use -ftemplate-depth=N to increase recursive template instantiation depth">; +def note_template_recursion_depth + : Note<"use -ftemplate-depth=N to increase recursive template " + "instantiation depth">, + NoSFINAE; def err_template_instantiate_within_definition : Error< "%select{implicit|explicit}0 instantiation of template %1 within its" @@ -6050,14 +6049,11 @@ def err_template_param_pack_default_arg : Error< def err_template_param_pack_must_be_last_template_parameter : Error< "template parameter pack must be the last template parameter">; -def err_template_parameter_pack_non_pack : Error< - "%select{template type|non-type template|template template}0 parameter" - "%select{| pack}1 conflicts with previous %select{template type|" - "non-type template|template template}0 parameter%select{ pack|}1">; -def note_template_parameter_pack_non_pack : Note< - "%select{template type|non-type template|template template}0 parameter" - "%select{| pack}1 does not match %select{template type|non-type template" - "|template template}0 parameter%select{ pack|}1 in template argument">; +def err_template_parameter_pack_non_pack + : Error<"%select{template type|non-type template|template template}0 " + "parameter" + "%select{| pack}1 conflicts with previous %select{template type|" + "non-type template|template template}0 parameter%select{ pack|}1">; def note_template_parameter_pack_here : Note< "previous %select{template type|non-type template|template template}0 " "parameter%select{| pack}1 declared here">; diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 2bd6be2..3e464d9 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -12026,7 +12026,7 @@ public: bool *ConstraintsNotSatisfied = nullptr); bool CheckTemplateTypeArgument( - TemplateTypeParmDecl *Param, TemplateArgumentLoc &Arg, + TemplateArgumentLoc &Arg, SmallVectorImpl<TemplateArgument> &SugaredConverted, SmallVectorImpl<TemplateArgument> &CanonicalConverted); @@ -12066,9 +12066,13 @@ public: TemplateTemplateParmDecl *Param, const TemplateArgumentLoc &Arg); + /// Print the given named declaration to a string, + /// using the current PrintingPolicy, except that + /// TerseOutput will always be set. + SmallString<128> toTerseString(const NamedDecl &D) const; + void NoteTemplateLocation(const NamedDecl &Decl, std::optional<SourceRange> ParamRange = {}); - void NoteTemplateParameterLocation(const NamedDecl &Decl); /// Given a non-type template argument that refers to a /// declaration and the type of its corresponding non-type template @@ -12183,15 +12187,13 @@ public: bool TemplateParameterListsAreEqual( const TemplateCompareNewDeclInfo &NewInstFrom, TemplateParameterList *New, const NamedDecl *OldInstFrom, TemplateParameterList *Old, bool Complain, - TemplateParameterListEqualKind Kind, - SourceLocation TemplateArgLoc = SourceLocation()); + TemplateParameterListEqualKind Kind); - bool TemplateParameterListsAreEqual( - TemplateParameterList *New, TemplateParameterList *Old, bool Complain, - TemplateParameterListEqualKind Kind, - SourceLocation TemplateArgLoc = SourceLocation()) { + bool TemplateParameterListsAreEqual(TemplateParameterList *New, + TemplateParameterList *Old, bool Complain, + TemplateParameterListEqualKind Kind) { return TemplateParameterListsAreEqual(nullptr, New, nullptr, Old, Complain, - Kind, TemplateArgLoc); + Kind); } /// Check whether a template can be declared within this scope. @@ -13088,6 +13090,11 @@ public: /// We are performing partial ordering for template template parameters. PartialOrderingTTP, + + /// We are Checking a Template Parameter, so for any diagnostics which + /// occur in this scope, we will add a context note which points to this + /// template parameter. + CheckTemplateParameter, } Kind; /// Was the enclosing context a non-instantiation SFINAE context? @@ -13318,6 +13325,10 @@ public: PartialOrderingTTP, TemplateDecl *PArg, SourceRange InstantiationRange = SourceRange()); + struct CheckTemplateParameter {}; + /// \brief Note that we are checking a template parameter. + InstantiatingTemplate(Sema &SemaRef, CheckTemplateParameter); + /// Note that we have finished instantiating this template. void Clear(); @@ -13335,8 +13346,6 @@ public: Sema &SemaRef; bool Invalid; bool AlreadyInstantiating; - bool CheckInstantiationDepth(SourceLocation PointOfInstantiation, - SourceRange InstantiationRange); InstantiatingTemplate(Sema &SemaRef, CodeSynthesisContext::SynthesisKind Kind, @@ -13351,6 +13360,30 @@ public: InstantiatingTemplate &operator=(const InstantiatingTemplate &) = delete; }; + /// For any diagnostics which occur within its scope, adds a context note + /// pointing to the declaration of the template parameter. + struct CheckTemplateParameterRAII : InstantiatingTemplate { + CheckTemplateParameterRAII(Sema &S, NamedDecl *Param = nullptr) + : InstantiatingTemplate(S, CheckTemplateParameter()), + Context(isInvalid() ? nullptr : &S.CodeSynthesisContexts.back()) { + setParam(Param); + } + + void setParam(NamedDecl *Param) { + assert(!Param || Param->isTemplateParameter()); + if (isInvalid()) + return; + Context->Entity = Param; + Context->PointOfInstantiation = + Param ? Param->getLocation() : SourceLocation(); + Context->InstantiationRange = + Param ? Param->getSourceRange() : SourceRange(); + } + + private: + Sema::CodeSynthesisContext *Context; + }; + bool SubstTemplateArgument(const TemplateArgumentLoc &Input, const MultiLevelTemplateArgumentList &TemplateArgs, TemplateArgumentLoc &Output, @@ -13529,7 +13562,7 @@ public: ~ArgPackSubstIndexRAII() { Self.ArgPackSubstIndex = OldSubstIndex; } }; - void pushCodeSynthesisContext(CodeSynthesisContext Ctx); + bool pushCodeSynthesisContext(CodeSynthesisContext Ctx); void popCodeSynthesisContext(); void PrintContextStack(InstantiationContextDiagFuncRef DiagFunc) { diff --git a/clang/lib/Frontend/FrontendActions.cpp b/clang/lib/Frontend/FrontendActions.cpp index 7424958..a73e0a6 100644 --- a/clang/lib/Frontend/FrontendActions.cpp +++ b/clang/lib/Frontend/FrontendActions.cpp @@ -418,7 +418,8 @@ public: } private: - static std::string toString(CodeSynthesisContext::SynthesisKind Kind) { + static std::optional<std::string> + toString(CodeSynthesisContext::SynthesisKind Kind) { switch (Kind) { case CodeSynthesisContext::TemplateInstantiation: return "TemplateInstantiation"; @@ -476,8 +477,10 @@ private: return "TypeAliasTemplateInstantiation"; case CodeSynthesisContext::PartialOrderingTTP: return "PartialOrderingTTP"; + case CodeSynthesisContext::CheckTemplateParameter: + return std::nullopt; } - return ""; + return std::nullopt; } template <bool BeginInstantiation> @@ -485,12 +488,14 @@ private: const CodeSynthesisContext &Inst) { std::string YAML; { + std::optional<TemplightEntry> Entry = + getTemplightEntry<BeginInstantiation>(TheSema, Inst); + if (!Entry) + return; llvm::raw_string_ostream OS(YAML); llvm::yaml::Output YO(OS); - TemplightEntry Entry = - getTemplightEntry<BeginInstantiation>(TheSema, Inst); llvm::yaml::EmptyContext Context; - llvm::yaml::yamlize(YO, Entry, true, Context); + llvm::yaml::yamlize(YO, *Entry, true, Context); } Out << "---" << YAML << "\n"; } @@ -570,10 +575,13 @@ private: } template <bool BeginInstantiation> - static TemplightEntry getTemplightEntry(const Sema &TheSema, - const CodeSynthesisContext &Inst) { + static std::optional<TemplightEntry> + getTemplightEntry(const Sema &TheSema, const CodeSynthesisContext &Inst) { TemplightEntry Entry; - Entry.Kind = toString(Inst.Kind); + std::optional<std::string> Kind = toString(Inst.Kind); + if (!Kind) + return std::nullopt; + Entry.Kind = *Kind; Entry.Event = BeginInstantiation ? "Begin" : "End"; llvm::raw_string_ostream OS(Entry.Name); printEntryName(TheSema, Inst.Entity, OS); diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index c971293..e79ac26 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -7342,7 +7342,7 @@ static void CheckCXX98CompatAccessibleCopy(Sema &S, void InitializationSequence::PrintInitLocationNote(Sema &S, const InitializedEntity &Entity) { - if (Entity.isParamOrTemplateParamKind() && Entity.getDecl()) { + if (Entity.isParameterKind() && Entity.getDecl()) { if (Entity.getDecl()->getLocation().isInvalid()) return; @@ -7351,9 +7351,8 @@ void InitializationSequence::PrintInitLocationNote(Sema &S, << Entity.getDecl()->getDeclName(); else S.Diag(Entity.getDecl()->getLocation(), diag::note_parameter_here); - } - else if (Entity.getKind() == InitializedEntity::EK_RelatedResult && - Entity.getMethodDecl()) + } else if (Entity.getKind() == InitializedEntity::EK_RelatedResult && + Entity.getMethodDecl()) S.Diag(Entity.getMethodDecl()->getLocation(), diag::note_method_return_type_change) << Entity.getMethodDecl()->getDeclName(); diff --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp index fbc2e7e..abd030b 100644 --- a/clang/lib/Sema/SemaLambda.cpp +++ b/clang/lib/Sema/SemaLambda.cpp @@ -1525,13 +1525,16 @@ void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro, TemplateParameterList *TemplateParams = getGenericLambdaTemplateParameterList(LSI, *this); if (TemplateParams) { - for (const auto *TP : TemplateParams->asArray()) { + CheckTemplateParameterRAII CTP(*this); + for (auto *TP : TemplateParams->asArray()) { if (!TP->getIdentifier()) continue; + CTP.setParam(TP); for (const auto &Capture : Intro.Captures) { if (Capture.Id == TP->getIdentifier()) { Diag(Capture.Loc, diag::err_template_param_shadow) << Capture.Id; - NoteTemplateParameterLocation(*TP); + // forget we already emitted this stack. + LastEmittedCodeSynthesisContextDepth = 0; } } } diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp index 25728de..305aab6 100644 --- a/clang/lib/Sema/SemaLookup.cpp +++ b/clang/lib/Sema/SemaLookup.cpp @@ -1613,9 +1613,13 @@ llvm::DenseSet<Module*> &Sema::getLookupModules() { unsigned N = CodeSynthesisContexts.size(); for (unsigned I = CodeSynthesisContextLookupModules.size(); I != N; ++I) { - Module *M = CodeSynthesisContexts[I].Entity ? - getDefiningModule(*this, CodeSynthesisContexts[I].Entity) : - nullptr; + auto &Ctx = CodeSynthesisContexts[I]; + // FIXME: Are there any other context kinds that shouldn't be looked at + // here? + if (Ctx.Kind == CodeSynthesisContext::PartialOrderingTTP || + Ctx.Kind == CodeSynthesisContext::CheckTemplateParameter) + continue; + Module *M = Ctx.Entity ? getDefiningModule(*this, Ctx.Entity) : nullptr; if (M && !LookupModulesCache.insert(M).second) M = nullptr; CodeSynthesisContextLookupModules.push_back(M); @@ -3738,7 +3742,8 @@ Sema::LookupLiteralOperator(Scope *S, LookupResult &R, TemplateParameterList *Params = FD->getTemplateParameters(); if (Params->size() == 1) { IsTemplate = true; - if (!Params->getParam(0)->isTemplateParameterPack() && !StringLit) { + NamedDecl *Param = Params->getParam(0); + if (!Param->isTemplateParameterPack() && !StringLit) { // Implied but not stated: user-defined integer and floating literals // only ever use numeric literal operator templates, not templates // taking a parameter of class type. @@ -3751,6 +3756,7 @@ Sema::LookupLiteralOperator(Scope *S, LookupResult &R, if (StringLit) { SFINAETrap Trap(*this); CheckTemplateArgumentInfo CTAI; + CheckTemplateParameterRAII CTP(*this, Param); TemplateArgumentLoc Arg( TemplateArgument(StringLit, /*IsCanonical=*/false), StringLit); if (CheckTemplateArgument( diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index 3ebbb30..ef789f6 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -921,9 +921,11 @@ void Sema::DiagnoseTemplateParameterShadow(SourceLocation Loc, Decl *PrevDecl, ? diag::ext_template_param_shadow : (SupportedForCompatibility ? diag::ext_compat_template_param_shadow : diag::err_template_param_shadow); - const auto *ND = cast<NamedDecl>(PrevDecl); + auto *ND = cast<NamedDecl>(PrevDecl); + CheckTemplateParameterRAII CTP(*this, ND); + // FIXME: Don't put the name in the diagnostic, unless there is no source + // location. Diag(Loc, DiagId) << ND->getDeclName(); - NoteTemplateParameterLocation(*ND); } TemplateDecl *Sema::AdjustDeclIfTemplate(Decl *&D) { @@ -5135,7 +5137,7 @@ TemplateNameKind Sema::ActOnTemplateName(Scope *S, } bool Sema::CheckTemplateTypeArgument( - TemplateTypeParmDecl *Param, TemplateArgumentLoc &AL, + TemplateArgumentLoc &AL, SmallVectorImpl<TemplateArgument> &SugaredConverted, SmallVectorImpl<TemplateArgument> &CanonicalConverted) { const TemplateArgument &Arg = AL.getArgument(); @@ -5191,7 +5193,6 @@ bool Sema::CheckTemplateTypeArgument( ? diag::ext_ms_template_type_arg_missing_typename : diag::err_template_arg_must_be_type_suggest) << FixItHint::CreateInsertion(Loc, "typename "); - NoteTemplateParameterLocation(*Param); // Recover by synthesizing a type using the location information that we // already have. @@ -5229,7 +5230,6 @@ bool Sema::CheckTemplateTypeArgument( // is not a type. SourceRange SR = AL.getSourceRange(); Diag(SR.getBegin(), diag::err_template_arg_must_be_type) << SR; - NoteTemplateParameterLocation(*Param); return true; } @@ -5502,8 +5502,8 @@ bool Sema::CheckTemplateArgument(NamedDecl *Param, TemplateArgumentLoc &ArgLoc, CheckTemplateArgumentInfo &CTAI, CheckTemplateArgumentKind CTAK) { // Check template type parameters. - if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param)) - return CheckTemplateTypeArgument(TTP, ArgLoc, CTAI.SugaredConverted, + if (isa<TemplateTypeParmDecl>(Param)) + return CheckTemplateTypeArgument(ArgLoc, CTAI.SugaredConverted, CTAI.CanonicalConverted); const TemplateArgument &Arg = ArgLoc.getArgument(); @@ -5646,8 +5646,6 @@ bool Sema::CheckTemplateArgument(NamedDecl *Param, TemplateArgumentLoc &ArgLoc, // therefore cannot be a non-type template argument. Diag(ArgLoc.getLocation(), diag::err_template_arg_must_be_expr) << ArgLoc.getSourceRange(); - NoteTemplateParameterLocation(*Param); - return true; case TemplateArgument::Type: { @@ -5667,7 +5665,6 @@ bool Sema::CheckTemplateArgument(NamedDecl *Param, TemplateArgumentLoc &ArgLoc, Diag(SR.getBegin(), diag::err_template_arg_nontype_ambig) << SR << T; else Diag(SR.getBegin(), diag::err_template_arg_must_be_expr) << SR; - NoteTemplateParameterLocation(*Param); return true; } @@ -5771,11 +5768,11 @@ bool Sema::CheckTemplateArgument(NamedDecl *Param, TemplateArgumentLoc &ArgLoc, } /// Diagnose a missing template argument. -template<typename TemplateParmDecl> +template <typename TemplateParmDecl> static bool diagnoseMissingArgument(Sema &S, SourceLocation Loc, - TemplateDecl *TD, - const TemplateParmDecl *D, - TemplateArgumentListInfo &Args) { + TemplateDecl *TD, const TemplateParmDecl *D, + TemplateArgumentListInfo &Args, + bool MatchingTTP) { // Dig out the most recent declaration of the template parameter; there may be // declarations of the template that are more recent than TD. D = cast<TemplateParmDecl>(cast<TemplateDecl>(TD->getMostRecentDecl()) @@ -5793,16 +5790,12 @@ static bool diagnoseMissingArgument(Sema &S, SourceLocation Loc, return true; } + SourceLocation DiagLoc = Args.getRAngleLoc(); // FIXME: If there's a more recent default argument that *is* visible, // diagnose that it was declared too late. - - TemplateParameterList *Params = TD->getTemplateParameters(); - - S.Diag(Loc, diag::err_template_arg_list_different_arity) - << /*not enough args*/0 - << (int)S.getTemplateNameKindForDiagnostics(TemplateName(TD)) - << TD; - S.NoteTemplateLocation(*TD, Params->getSourceRange()); + S.Diag(DiagLoc.isValid() ? DiagLoc : Loc, + MatchingTTP ? diag::err_template_template_param_missing_param + : diag::err_template_param_missing_arg); return true; } @@ -5836,11 +5829,14 @@ bool Sema::CheckTemplateArgumentList( SmallVector<TemplateArgument, 2> CanonicalArgumentPack; unsigned ArgIdx = 0, NumArgs = NewArgs.size(); LocalInstantiationScope InstScope(*this, true); + CheckTemplateParameterRAII CTP(*this); for (TemplateParameterList::iterator ParamBegin = Params->begin(), ParamEnd = Params->end(), Param = ParamBegin; Param != ParamEnd; /* increment in loop */) { + CTP.setParam(*Param); + if (size_t ParamIdx = Param - ParamBegin; DefaultArgs && ParamIdx >= DefaultArgs.StartPos) { // All written arguments should have been consumed by this point. @@ -5877,11 +5873,9 @@ bool Sema::CheckTemplateArgumentList( continue; } else if (ArgIdx == NumArgs && !PartialTemplateArgs) { // Not enough arguments for this parameter pack. - Diag(TemplateLoc, diag::err_template_arg_list_different_arity) - << /*not enough args*/0 - << (int)getTemplateNameKindForDiagnostics(TemplateName(Template)) - << Template; - NoteTemplateLocation(*Template, Params->getSourceRange()); + Diag(RAngleLoc, CTAI.MatchingTTP + ? diag::err_template_template_param_missing_param + : diag::err_template_param_missing_arg); return true; } } @@ -5919,6 +5913,7 @@ bool Sema::CheckTemplateArgumentList( SmallVector<TemplateArgument, 4> Args(ParamEnd - Param); for (TemplateParameterList::iterator First = Param; Param != ParamEnd; ++Param) { + CTP.setParam(*Param); TemplateArgument &Arg = Args[Param - First]; Arg = ArgLoc.getArgument(); if (!(*Param)->isTemplateParameterPack() || @@ -5959,7 +5954,6 @@ bool Sema::CheckTemplateArgumentList( diag::err_template_expansion_into_fixed_list) << (isa<ConceptDecl>(Template) ? 1 : 0) << ArgLoc.getSourceRange(); - NoteTemplateParameterLocation(**Param); return true; } } @@ -6066,14 +6060,14 @@ bool Sema::CheckTemplateArgumentList( if (!HasDefaultArg) { if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*Param)) return diagnoseMissingArgument(*this, TemplateLoc, Template, TTP, - NewArgs); + NewArgs, CTAI.MatchingTTP); if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(*Param)) return diagnoseMissingArgument(*this, TemplateLoc, Template, NTTP, - NewArgs); + NewArgs, CTAI.MatchingTTP); return diagnoseMissingArgument(*this, TemplateLoc, Template, cast<TemplateTemplateParmDecl>(*Param), - NewArgs); + NewArgs, CTAI.MatchingTTP); } return true; } @@ -6109,6 +6103,7 @@ bool Sema::CheckTemplateArgumentList( ++Param; ++ArgIdx; } + CTP.Clear(); // If we're performing a partial argument substitution, allow any trailing // pack expansions; they might be empty. This can happen even if @@ -6129,8 +6124,7 @@ bool Sema::CheckTemplateArgumentList( // If we have any leftover arguments, then there were too many arguments. // Complain and fail. if (ArgIdx < NumArgs) { - Diag(TemplateLoc, diag::err_template_arg_list_different_arity) - << /*too many args*/1 + Diag(TemplateLoc, diag::err_template_too_many_args) << (int)getTemplateNameKindForDiagnostics(TemplateName(Template)) << Template << SourceRange(NewArgs[ArgIdx].getLocation(), NewArgs.getRAngleLoc()); @@ -6558,8 +6552,6 @@ isNullPointerValueTemplateArgument(Sema &S, NamedDecl *Param, << Arg->getType() << Arg->getSourceRange(); for (unsigned I = 0, N = Notes.size(); I != N; ++I) S.Diag(Notes[I].first, Notes[I].second); - - S.NoteTemplateParameterLocation(*Param); return NPV_Error; } @@ -6584,8 +6576,7 @@ isNullPointerValueTemplateArgument(Sema &S, NamedDecl *Param, // The types didn't match, but we know we got a null pointer; complain, // then recover as if the types were correct. S.Diag(Arg->getExprLoc(), diag::err_template_arg_wrongtype_null_constant) - << Arg->getType() << ParamType << Arg->getSourceRange(); - S.NoteTemplateParameterLocation(*Param); + << Arg->getType() << ParamType << Arg->getSourceRange(); return NPV_NullPointer; } @@ -6594,8 +6585,7 @@ isNullPointerValueTemplateArgument(Sema &S, NamedDecl *Param, // We could just return NPV_NotNullPointer, but we can print a better // message with the information we have here. S.Diag(Arg->getExprLoc(), diag::err_template_arg_invalid) - << EvalResult.Val.getAsString(S.Context, ParamType); - S.NoteTemplateParameterLocation(*Param); + << EvalResult.Val.getAsString(S.Context, ParamType); return NPV_Error; } @@ -6607,7 +6597,6 @@ isNullPointerValueTemplateArgument(Sema &S, NamedDecl *Param, << ParamType << FixItHint::CreateInsertion(Arg->getBeginLoc(), Code) << FixItHint::CreateInsertion(S.getLocForEndOfToken(Arg->getEndLoc()), ")"); - S.NoteTemplateParameterLocation(*Param); return NPV_NullPointer; } @@ -6649,7 +6638,6 @@ CheckTemplateArgumentIsCompatibleWithParameter(Sema &S, NamedDecl *Param, S.Diag(Arg->getBeginLoc(), diag::err_template_arg_ref_bind_ignores_quals) << ParamType << Arg->getType() << Arg->getSourceRange(); - S.NoteTemplateParameterLocation(*Param); return true; } } @@ -6667,7 +6655,6 @@ CheckTemplateArgumentIsCompatibleWithParameter(Sema &S, NamedDecl *Param, else S.Diag(Arg->getBeginLoc(), diag::err_template_arg_not_convertible) << ArgIn->getType() << ParamType << Arg->getSourceRange(); - S.NoteTemplateParameterLocation(*Param); return true; } } @@ -6807,7 +6794,6 @@ static bool CheckTemplateArgumentAddressOfObjectOrFunction( if (!Entity) { S.Diag(Arg->getBeginLoc(), diag::err_template_arg_not_decl_ref) << Arg->getSourceRange(); - S.NoteTemplateParameterLocation(*Param); return true; } @@ -6815,7 +6801,6 @@ static bool CheckTemplateArgumentAddressOfObjectOrFunction( if (isa<FieldDecl>(Entity) || isa<IndirectFieldDecl>(Entity)) { S.Diag(Arg->getBeginLoc(), diag::err_template_arg_field) << Entity << Arg->getSourceRange(); - S.NoteTemplateParameterLocation(*Param); return true; } @@ -6824,7 +6809,6 @@ static bool CheckTemplateArgumentAddressOfObjectOrFunction( if (!Method->isStatic()) { S.Diag(Arg->getBeginLoc(), diag::err_template_arg_method) << Method << Arg->getSourceRange(); - S.NoteTemplateParameterLocation(*Param); return true; } } @@ -6864,7 +6848,6 @@ static bool CheckTemplateArgumentAddressOfObjectOrFunction( if (Var->getType()->isReferenceType()) { S.Diag(Arg->getBeginLoc(), diag::err_template_arg_reference_var) << Var->getType() << Arg->getSourceRange(); - S.NoteTemplateParameterLocation(*Param); return true; } @@ -6884,15 +6867,12 @@ static bool CheckTemplateArgumentAddressOfObjectOrFunction( if (!S.Context.hasSameUnqualifiedType(Entity->getType(), ParamType.getNonReferenceType())) { S.Diag(AddrOpLoc, diag::err_template_arg_address_of_non_pointer) - << ParamType; - S.NoteTemplateParameterLocation(*Param); + << ParamType; return true; } S.Diag(AddrOpLoc, diag::err_template_arg_address_of_non_pointer) - << ParamType - << FixItHint::CreateRemoval(AddrOpLoc); - S.NoteTemplateParameterLocation(*Param); + << ParamType << FixItHint::CreateRemoval(AddrOpLoc); ArgType = Entity->getType(); } @@ -6913,15 +6893,12 @@ static bool CheckTemplateArgumentAddressOfObjectOrFunction( ArgType = S.Context.getPointerType(Entity->getType()); if (!S.Context.hasSameUnqualifiedType(ArgType, ParamType)) { S.Diag(Arg->getBeginLoc(), diag::err_template_arg_not_address_of) - << ParamType; - S.NoteTemplateParameterLocation(*Param); + << ParamType; return true; } S.Diag(Arg->getBeginLoc(), diag::err_template_arg_not_address_of) - << ParamType << FixItHint::CreateInsertion(Arg->getBeginLoc(), "&"); - - S.NoteTemplateParameterLocation(*Param); + << ParamType << FixItHint::CreateInsertion(Arg->getBeginLoc(), "&"); } } @@ -7032,7 +7009,6 @@ static bool CheckTemplateArgumentPointerToMember( // We can't perform this conversion. S.Diag(ResultArg->getBeginLoc(), diag::err_template_arg_not_convertible) << ResultArg->getType() << ParamType << ResultArg->getSourceRange(); - S.NoteTemplateParameterLocation(*Param); return true; } @@ -7142,7 +7118,6 @@ ExprResult Sema::CheckTemplateArgument(NamedDecl *Param, QualType ParamType, diag::err_non_type_template_parm_type_deduction_failure) << Param->getDeclName() << NTTP->getType() << Arg->getType() << Arg->getSourceRange(); - NoteTemplateParameterLocation(*Param); return ExprError(); } ParamType = SubstAutoTypeDependent(ParamType); @@ -7154,10 +7129,8 @@ ExprResult Sema::CheckTemplateArgument(NamedDecl *Param, QualType ParamType, // declaration, but here we'll pass the argument location because that's // where the parameter type is deduced. ParamType = CheckNonTypeTemplateParameterType(ParamType, Arg->getExprLoc()); - if (ParamType.isNull()) { - NoteTemplateParameterLocation(*Param); + if (ParamType.isNull()) return ExprError(); - } } // We should have already dropped all cv-qualifiers by now. @@ -7197,7 +7170,6 @@ ExprResult Sema::CheckTemplateArgument(NamedDecl *Param, QualType ParamType, // template parameter type. Diag(StartLoc, diag::err_deduced_non_type_template_arg_type_mismatch) << Arg->getType() << ParamType.getUnqualifiedType(); - NoteTemplateParameterLocation(*Param); return ExprError(); } @@ -7280,10 +7252,8 @@ ExprResult Sema::CheckTemplateArgument(NamedDecl *Param, QualType ParamType, DeductionArg, ParamType, StrictCheck ? CCEKind::TempArgStrict : CCEKind::TemplateArg, Param); assert(!ArgResult.isUnset()); - if (ArgResult.isInvalid()) { - NoteTemplateParameterLocation(*Param); + if (ArgResult.isInvalid()) return ExprError(); - } } else { ArgResult = DeductionArg; } @@ -7449,7 +7419,6 @@ ExprResult Sema::CheckTemplateArgument(NamedDecl *Param, QualType ParamType, if (!ArgType->isIntegralOrEnumerationType()) { Diag(Arg->getBeginLoc(), diag::err_template_arg_not_integral_or_enumeral) << ArgType << Arg->getSourceRange(); - NoteTemplateParameterLocation(*Param); return ExprError(); } if (!Arg->isValueDependent()) { @@ -7488,7 +7457,6 @@ ExprResult Sema::CheckTemplateArgument(NamedDecl *Param, QualType ParamType, // We can't perform this conversion. Diag(StartLoc, diag::err_template_arg_not_convertible) << Arg->getType() << ParamType << Arg->getSourceRange(); - NoteTemplateParameterLocation(*Param); return ExprError(); } @@ -7534,7 +7502,6 @@ ExprResult Sema::CheckTemplateArgument(NamedDecl *Param, QualType ParamType, Diag(Arg->getBeginLoc(), diag::warn_template_arg_negative) << toString(OldValue, 10) << toString(Value, 10) << ParamType << Arg->getSourceRange(); - NoteTemplateParameterLocation(*Param); } // Complain if we overflowed the template parameter's type. @@ -7545,12 +7512,10 @@ ExprResult Sema::CheckTemplateArgument(NamedDecl *Param, QualType ParamType, RequiredBits = OldValue.getActiveBits() + 1; else RequiredBits = OldValue.getSignificantBits(); - if (RequiredBits > AllowedBits) { + if (RequiredBits > AllowedBits) Diag(Arg->getBeginLoc(), diag::warn_template_arg_too_large) << toString(OldValue, 10) << toString(Value, 10) << ParamType << Arg->getSourceRange(); - NoteTemplateParameterLocation(*Param); - } } QualType T = ParamType->isEnumeralType() ? ParamType : IntegerType; @@ -7676,7 +7641,6 @@ ExprResult Sema::CheckTemplateArgument(NamedDecl *Param, QualType ParamType, case NPV_NotNullPointer: Diag(Arg->getExprLoc(), diag::err_template_arg_not_convertible) << Arg->getType() << ParamType; - NoteTemplateParameterLocation(*Param); return ExprError(); case NPV_Error: @@ -7704,7 +7668,7 @@ ExprResult Sema::CheckTemplateArgument(NamedDecl *Param, QualType ParamType, static void DiagnoseTemplateParameterListArityMismatch( Sema &S, TemplateParameterList *New, TemplateParameterList *Old, - Sema::TemplateParameterListEqualKind Kind, SourceLocation TemplateArgLoc); + Sema::TemplateParameterListEqualKind Kind); bool Sema::CheckDeclCompatibleWithTemplateTemplate( TemplateDecl *Template, TemplateTemplateParmDecl *Param, @@ -7832,7 +7796,6 @@ bool Sema::CheckTemplateTemplateArgument(TemplateTemplateParmDecl *Param, Diag(Arg.getLocation(), diag::err_template_template_parameter_not_at_least_as_constrained) << Template << Param << Arg.getSourceRange(); - Diag(Param->getLocation(), diag::note_entity_declared_at) << Param; Diag(Template->getLocation(), diag::note_entity_declared_at) << Template; MaybeEmitAmbiguousAtomicConstraintsDiagnostic(Param, ParamsAC, Template, TemplateAC); @@ -7841,25 +7804,24 @@ bool Sema::CheckTemplateTemplateArgument(TemplateTemplateParmDecl *Param, return false; } -static Sema::SemaDiagnosticBuilder noteLocation(Sema &S, const NamedDecl &Decl, - unsigned HereDiagID, - unsigned ExternalDiagID) { - if (Decl.getLocation().isValid()) - return S.Diag(Decl.getLocation(), HereDiagID); - +SmallString<128> Sema::toTerseString(const NamedDecl &D) const { SmallString<128> Str; llvm::raw_svector_ostream Out(Str); - PrintingPolicy PP = S.getPrintingPolicy(); + PrintingPolicy PP = getPrintingPolicy(); PP.TerseOutput = 1; - Decl.print(Out, PP); - return S.Diag(Decl.getLocation(), ExternalDiagID) << Out.str(); + D.print(Out, PP); + return Str; } +// FIXME: Transform this into a context note. void Sema::NoteTemplateLocation(const NamedDecl &Decl, std::optional<SourceRange> ParamRange) { + bool HasLoc = Decl.getLocation().isValid(); SemaDiagnosticBuilder DB = - noteLocation(*this, Decl, diag::note_template_decl_here, - diag::note_template_decl_external); + Diag(Decl.getLocation(), HasLoc ? diag::note_template_decl_here + : diag::note_template_decl_external); + if (!HasLoc) + DB << toTerseString(Decl).str(); if (ParamRange && ParamRange->isValid()) { assert(Decl.getLocation().isValid() && "Parameter range has location when Decl does not"); @@ -7867,11 +7829,6 @@ void Sema::NoteTemplateLocation(const NamedDecl &Decl, } } -void Sema::NoteTemplateParameterLocation(const NamedDecl &Decl) { - noteLocation(*this, Decl, diag::note_template_param_here, - diag::note_template_param_external); -} - /// Given a non-type template argument that refers to a /// declaration and the type of its corresponding non-type template /// parameter, produce an expression that properly refers to that @@ -8149,21 +8106,17 @@ Sema::BuildExpressionFromNonTypeTemplateArgument(const TemplateArgument &Arg, } /// Match two template parameters within template parameter lists. -static bool MatchTemplateParameterKind( - Sema &S, NamedDecl *New, - const Sema::TemplateCompareNewDeclInfo &NewInstFrom, NamedDecl *Old, - const NamedDecl *OldInstFrom, bool Complain, - Sema::TemplateParameterListEqualKind Kind, SourceLocation TemplateArgLoc) { +static bool +MatchTemplateParameterKind(Sema &S, NamedDecl *New, + const Sema::TemplateCompareNewDeclInfo &NewInstFrom, + NamedDecl *Old, const NamedDecl *OldInstFrom, + bool Complain, + Sema::TemplateParameterListEqualKind Kind) { // Check the actual kind (type, non-type, template). if (Old->getKind() != New->getKind()) { if (Complain) { - unsigned NextDiag = diag::err_template_param_different_kind; - if (TemplateArgLoc.isValid()) { - S.Diag(TemplateArgLoc, diag::err_template_arg_template_params_mismatch); - NextDiag = diag::note_template_param_different_kind; - } - S.Diag(New->getLocation(), NextDiag) - << (Kind != Sema::TPL_TemplateMatch); + S.Diag(New->getLocation(), diag::err_template_param_different_kind) + << (Kind != Sema::TPL_TemplateMatch); S.Diag(Old->getLocation(), diag::note_template_prev_declaration) << (Kind != Sema::TPL_TemplateMatch); } @@ -8177,18 +8130,11 @@ static bool MatchTemplateParameterKind( // a parameter pack where the template template argument does not. if (Old->isTemplateParameterPack() != New->isTemplateParameterPack()) { if (Complain) { - unsigned NextDiag = diag::err_template_parameter_pack_non_pack; - if (TemplateArgLoc.isValid()) { - S.Diag(TemplateArgLoc, - diag::err_template_arg_template_params_mismatch); - NextDiag = diag::note_template_parameter_pack_non_pack; - } - unsigned ParamKind = isa<TemplateTypeParmDecl>(New)? 0 : isa<NonTypeTemplateParmDecl>(New)? 1 : 2; - S.Diag(New->getLocation(), NextDiag) - << ParamKind << New->isParameterPack(); + S.Diag(New->getLocation(), diag::err_template_parameter_pack_non_pack) + << ParamKind << New->isParameterPack(); S.Diag(Old->getLocation(), diag::note_template_parameter_pack_here) << ParamKind << Old->isParameterPack(); } @@ -8215,13 +8161,8 @@ static bool MatchTemplateParameterKind( QualType NewType = S.Context.getUnconstrainedType(NewNTTP->getType()); if (!S.Context.hasSameType(OldType, NewType)) { if (Complain) { - unsigned NextDiag = diag::err_template_nontype_parm_different_type; - if (TemplateArgLoc.isValid()) { - S.Diag(TemplateArgLoc, - diag::err_template_arg_template_params_mismatch); - NextDiag = diag::note_template_nontype_parm_different_type; - } - S.Diag(NewNTTP->getLocation(), NextDiag) + S.Diag(NewNTTP->getLocation(), + diag::err_template_nontype_parm_different_type) << NewNTTP->getType() << (Kind != Sema::TPL_TemplateMatch); S.Diag(OldNTTP->getLocation(), diag::note_template_nontype_parm_prev_declaration) @@ -8244,8 +8185,7 @@ static bool MatchTemplateParameterKind( OldTTP->getTemplateParameters(), Complain, (Kind == Sema::TPL_TemplateMatch ? Sema::TPL_TemplateTemplateParmMatch - : Kind), - TemplateArgLoc)) + : Kind))) return false; } @@ -8297,21 +8237,12 @@ static bool MatchTemplateParameterKind( /// Diagnose a known arity mismatch when comparing template argument /// lists. -static -void DiagnoseTemplateParameterListArityMismatch(Sema &S, - TemplateParameterList *New, - TemplateParameterList *Old, - Sema::TemplateParameterListEqualKind Kind, - SourceLocation TemplateArgLoc) { - unsigned NextDiag = diag::err_template_param_list_different_arity; - if (TemplateArgLoc.isValid()) { - S.Diag(TemplateArgLoc, diag::err_template_arg_template_params_mismatch); - NextDiag = diag::note_template_param_list_different_arity; - } - S.Diag(New->getTemplateLoc(), NextDiag) - << (New->size() > Old->size()) - << (Kind != Sema::TPL_TemplateMatch) - << SourceRange(New->getTemplateLoc(), New->getRAngleLoc()); +static void DiagnoseTemplateParameterListArityMismatch( + Sema &S, TemplateParameterList *New, TemplateParameterList *Old, + Sema::TemplateParameterListEqualKind Kind) { + S.Diag(New->getTemplateLoc(), diag::err_template_param_list_different_arity) + << (New->size() > Old->size()) << (Kind != Sema::TPL_TemplateMatch) + << SourceRange(New->getTemplateLoc(), New->getRAngleLoc()); S.Diag(Old->getTemplateLoc(), diag::note_template_prev_declaration) << (Kind != Sema::TPL_TemplateMatch) << SourceRange(Old->getTemplateLoc(), Old->getRAngleLoc()); @@ -8320,11 +8251,10 @@ void DiagnoseTemplateParameterListArityMismatch(Sema &S, bool Sema::TemplateParameterListsAreEqual( const TemplateCompareNewDeclInfo &NewInstFrom, TemplateParameterList *New, const NamedDecl *OldInstFrom, TemplateParameterList *Old, bool Complain, - TemplateParameterListEqualKind Kind, SourceLocation TemplateArgLoc) { + TemplateParameterListEqualKind Kind) { if (Old->size() != New->size()) { if (Complain) - DiagnoseTemplateParameterListArityMismatch(*this, New, Old, Kind, - TemplateArgLoc); + DiagnoseTemplateParameterListArityMismatch(*this, New, Old, Kind); return false; } @@ -8342,21 +8272,18 @@ bool Sema::TemplateParameterListsAreEqual( OldParm != OldParmEnd; ++OldParm, ++NewParm) { if (NewParm == NewParmEnd) { if (Complain) - DiagnoseTemplateParameterListArityMismatch(*this, New, Old, Kind, - TemplateArgLoc); + DiagnoseTemplateParameterListArityMismatch(*this, New, Old, Kind); return false; } if (!MatchTemplateParameterKind(*this, *NewParm, NewInstFrom, *OldParm, - OldInstFrom, Complain, Kind, - TemplateArgLoc)) + OldInstFrom, Complain, Kind)) return false; } // Make sure we exhausted all of the arguments. if (NewParm != NewParmEnd) { if (Complain) - DiagnoseTemplateParameterListArityMismatch(*this, New, Old, Kind, - TemplateArgLoc); + DiagnoseTemplateParameterListArityMismatch(*this, New, Old, Kind); return false; } @@ -8664,7 +8591,6 @@ static bool CheckNonTypeTemplatePartialSpecializationArgs( S.Diag(IsDefaultArgument ? TemplateNameLoc : ArgExpr->getBeginLoc(), diag::err_dependent_typed_non_type_arg_in_partial_spec) << Param->getType(); - S.NoteTemplateParameterLocation(*Param); return true; } } @@ -8682,12 +8608,14 @@ bool Sema::CheckTemplatePartialSpecializationArgs( TemplateParameterList *TemplateParams = PrimaryTemplate->getTemplateParameters(); + CheckTemplateParameterRAII CTP(*this); for (unsigned I = 0, N = TemplateParams->size(); I != N; ++I) { NonTypeTemplateParmDecl *Param = dyn_cast<NonTypeTemplateParmDecl>(TemplateParams->getParam(I)); if (!Param) continue; + CTP.setParam(Param); if (CheckNonTypeTemplatePartialSpecializationArgs(*this, TemplateNameLoc, Param, &TemplateArgs[I], 1, I >= NumExplicit)) diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp index f6ee745..cbc64a7 100644 --- a/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -2980,7 +2980,7 @@ ConvertDeducedTemplateArgument(Sema &S, NamedDecl *Param, // arguments). S.Diag(Param->getLocation(), diag::err_template_arg_deduced_incomplete_pack) - << Arg << Param; + << Arg << Param; return true; } if (ConvertArg(InnerArg, SugaredPackedArgsBuilder.size())) @@ -3039,9 +3039,10 @@ static TemplateDeductionResult ConvertDeducedTemplateArguments( TemplateDeductionInfo &Info, Sema::CheckTemplateArgumentInfo &CTAI, LocalInstantiationScope *CurrentInstantiationScope, unsigned NumAlreadyConverted, bool *IsIncomplete) { + Sema::CheckTemplateParameterRAII CTP(S); for (unsigned I = 0, N = TemplateParams->size(); I != N; ++I) { NamedDecl *Param = TemplateParams->getParam(I); - + CTP.setParam(Param); // C++0x [temp.arg.explicit]p3: // A trailing template parameter pack (14.5.3) not otherwise deduced will // be deduced to an empty sequence of template arguments. diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp index 1ff94d7..0c8dec5 100644 --- a/clang/lib/Sema/SemaTemplateInstantiate.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -592,6 +592,7 @@ bool Sema::CodeSynthesisContext::isInstantiationRecord() const { case BuildingDeductionGuides: case TypeAliasTemplateInstantiation: case PartialOrderingTTP: + case CheckTemplateParameter: return false; // This function should never be called when Kind's value is Memoization. @@ -616,29 +617,30 @@ Sema::InstantiatingTemplate::InstantiatingTemplate( Invalid = true; return; } - Invalid = CheckInstantiationDepth(PointOfInstantiation, InstantiationRange); + + CodeSynthesisContext Inst; + Inst.Kind = Kind; + Inst.PointOfInstantiation = PointOfInstantiation; + Inst.Entity = Entity; + Inst.Template = Template; + Inst.TemplateArgs = TemplateArgs.data(); + Inst.NumTemplateArgs = TemplateArgs.size(); + Inst.DeductionInfo = DeductionInfo; + Inst.InstantiationRange = InstantiationRange; + Inst.InConstraintSubstitution = + Inst.Kind == CodeSynthesisContext::ConstraintSubstitution; + if (!SemaRef.CodeSynthesisContexts.empty()) + Inst.InConstraintSubstitution |= + SemaRef.CodeSynthesisContexts.back().InConstraintSubstitution; + + Invalid = SemaRef.pushCodeSynthesisContext(Inst); if (!Invalid) { - CodeSynthesisContext Inst; - Inst.Kind = Kind; - Inst.PointOfInstantiation = PointOfInstantiation; - Inst.Entity = Entity; - Inst.Template = Template; - Inst.TemplateArgs = TemplateArgs.data(); - Inst.NumTemplateArgs = TemplateArgs.size(); - Inst.DeductionInfo = DeductionInfo; - Inst.InstantiationRange = InstantiationRange; - Inst.InConstraintSubstitution = - Inst.Kind == CodeSynthesisContext::ConstraintSubstitution; - if (!SemaRef.CodeSynthesisContexts.empty()) - Inst.InConstraintSubstitution |= - SemaRef.CodeSynthesisContexts.back().InConstraintSubstitution; - - SemaRef.pushCodeSynthesisContext(Inst); - - AlreadyInstantiating = !Inst.Entity ? false : - !SemaRef.InstantiatingSpecializations - .insert({Inst.Entity->getCanonicalDecl(), Inst.Kind}) - .second; + AlreadyInstantiating = + !Inst.Entity + ? false + : !SemaRef.InstantiatingSpecializations + .insert({Inst.Entity->getCanonicalDecl(), Inst.Kind}) + .second; atTemplateBegin(SemaRef.TemplateInstCallbacks, SemaRef, Inst); } } @@ -832,20 +834,43 @@ Sema::InstantiatingTemplate::InstantiatingTemplate( Sema &SemaRef, SourceLocation ArgLoc, PartialOrderingTTP, TemplateDecl *PArg, SourceRange InstantiationRange) : InstantiatingTemplate(SemaRef, CodeSynthesisContext::PartialOrderingTTP, - ArgLoc, InstantiationRange, PArg) {} + ArgLoc, SourceRange(), PArg) {} + +Sema::InstantiatingTemplate::InstantiatingTemplate(Sema &SemaRef, + CheckTemplateParameter) + : InstantiatingTemplate( + SemaRef, CodeSynthesisContext::CheckTemplateParameter, + /*PointOfInstantiation*/ SourceLocation(), + /*InstantiationRange=*/SourceRange(), /*Entity=*/nullptr) {} -void Sema::pushCodeSynthesisContext(CodeSynthesisContext Ctx) { +bool Sema::pushCodeSynthesisContext(CodeSynthesisContext Ctx) { Ctx.SavedInNonInstantiationSFINAEContext = InNonInstantiationSFINAEContext; InNonInstantiationSFINAEContext = false; - CodeSynthesisContexts.push_back(Ctx); - - if (!Ctx.isInstantiationRecord()) + if (!Ctx.isInstantiationRecord()) { ++NonInstantiationEntries; + } else { + assert(SemaRef.NonInstantiationEntries <= + SemaRef.CodeSynthesisContexts.size()); + if ((SemaRef.CodeSynthesisContexts.size() - + SemaRef.NonInstantiationEntries) > + SemaRef.getLangOpts().InstantiationDepth) { + SemaRef.Diag(Ctx.PointOfInstantiation, + diag::err_template_recursion_depth_exceeded) + << SemaRef.getLangOpts().InstantiationDepth << Ctx.InstantiationRange; + SemaRef.Diag(Ctx.PointOfInstantiation, + diag::note_template_recursion_depth) + << SemaRef.getLangOpts().InstantiationDepth; + return true; + } + } + + CodeSynthesisContexts.push_back(Ctx); // Check to see if we're low on stack space. We can't do anything about this // from here, but we can at least warn the user. StackHandler.warnOnStackNearlyExhausted(Ctx.PointOfInstantiation); + return false; } void Sema::popCodeSynthesisContext() { @@ -907,25 +932,6 @@ static std::string convertCallArgsToString(Sema &S, return Result; } -bool Sema::InstantiatingTemplate::CheckInstantiationDepth( - SourceLocation PointOfInstantiation, - SourceRange InstantiationRange) { - assert(SemaRef.NonInstantiationEntries <= - SemaRef.CodeSynthesisContexts.size()); - if ((SemaRef.CodeSynthesisContexts.size() - - SemaRef.NonInstantiationEntries) - <= SemaRef.getLangOpts().InstantiationDepth) - return false; - - SemaRef.Diag(PointOfInstantiation, - diag::err_template_recursion_depth_exceeded) - << SemaRef.getLangOpts().InstantiationDepth - << InstantiationRange; - SemaRef.Diag(PointOfInstantiation, diag::note_template_recursion_depth) - << SemaRef.getLangOpts().InstantiationDepth; - return true; -} - void Sema::PrintInstantiationStack(InstantiationContextDiagFuncRef DiagFunc) { // Determine which template instantiations to skip, if any. unsigned SkipStart = CodeSynthesisContexts.size(), SkipEnd = SkipStart; @@ -1276,12 +1282,20 @@ void Sema::PrintInstantiationStack(InstantiationContextDiagFuncRef DiagFunc) { case CodeSynthesisContext::PartialOrderingTTP: DiagFunc(Active->PointOfInstantiation, PDiag(diag::note_template_arg_template_params_mismatch)); - if (SourceLocation ParamLoc = Active->Entity->getLocation(); - ParamLoc.isValid()) - DiagFunc(ParamLoc, PDiag(diag::note_template_prev_declaration) - << /*isTemplateTemplateParam=*/true - << Active->InstantiationRange); break; + case CodeSynthesisContext::CheckTemplateParameter: { + if (!Active->Entity) + break; + const auto &ND = *cast<NamedDecl>(Active->Entity); + if (SourceLocation Loc = ND.getLocation(); Loc.isValid()) { + DiagFunc(Loc, PDiag(diag::note_template_param_here) + << ND.getSourceRange()); + break; + } + DiagFunc(SourceLocation(), PDiag(diag::note_template_param_external) + << toTerseString(ND).str()); + break; + } } } } @@ -1325,6 +1339,7 @@ std::optional<TemplateDeductionInfo *> Sema::isSFINAEContext() const { case CodeSynthesisContext::DefaultTemplateArgumentChecking: case CodeSynthesisContext::RewritingOperatorAsSpaceship: case CodeSynthesisContext::PartialOrderingTTP: + case CodeSynthesisContext::CheckTemplateParameter: // A default template argument instantiation and substitution into // template parameters with arguments for prior parameters may or may // not be a SFINAE context; look further up the stack. diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index 0214078..995465ba 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -16307,6 +16307,8 @@ ExprResult TreeTransform<Derived>::TransformSubstNonTypeTemplateParmPackExpr( template <typename Derived> ExprResult TreeTransform<Derived>::TransformSubstNonTypeTemplateParmExpr( SubstNonTypeTemplateParmExpr *E) { + Sema::CheckTemplateParameterRAII CTP(SemaRef, E->getParameter()); + Expr *OrigReplacement = E->getReplacement()->IgnoreImplicitAsWritten(); ExprResult Replacement = getDerived().TransformExpr(OrigReplacement); if (Replacement.isInvalid()) diff --git a/clang/test/AST/ByteCode/cxx1z.cpp b/clang/test/AST/ByteCode/cxx1z.cpp index 57f9923..ca5f10f 100644 --- a/clang/test/AST/ByteCode/cxx1z.cpp +++ b/clang/test/AST/ByteCode/cxx1z.cpp @@ -1,7 +1,7 @@ // RUN: %clang_cc1 -fexperimental-new-constant-interpreter -std=c++17 -verify=expected,both %s // RUN: %clang_cc1 -std=c++17 -verify=ref,both %s -template<typename T, T val> struct A {}; +template<typename T, T val> struct A {}; // both-note 6{{template parameter is declared here}} namespace Temp { struct S { int n; }; constexpr S &addr(S &&s) { return s; } diff --git a/clang/test/AST/ByteCode/cxx20.cpp b/clang/test/AST/ByteCode/cxx20.cpp index 67bf9a7..ad40de3 100644 --- a/clang/test/AST/ByteCode/cxx20.cpp +++ b/clang/test/AST/ByteCode/cxx20.cpp @@ -905,7 +905,7 @@ namespace VirtDtor { } namespace TemporaryInNTTP { - template<auto n> struct B { /* ... */ }; + template<auto n> struct B { /* ... */ }; // both-note {{template parameter is declared here}} struct J1 { J1 *self=this; }; diff --git a/clang/test/AST/ByteCode/cxx2a.cpp b/clang/test/AST/ByteCode/cxx2a.cpp index 533173d..a13e675 100644 --- a/clang/test/AST/ByteCode/cxx2a.cpp +++ b/clang/test/AST/ByteCode/cxx2a.cpp @@ -242,7 +242,8 @@ namespace GH150705 { namespace DependentRequiresExpr { template <class T, - bool = []() -> bool { // both-error {{not a constant expression}} + bool = // both-note {{template parameter is declared here}} + []() -> bool { // both-error {{not a constant expression}} if (requires { T::type; }) return true; return false; diff --git a/clang/test/AST/ByteCode/cxx98.cpp b/clang/test/AST/ByteCode/cxx98.cpp index 1150a4e..c0587e1 100644 --- a/clang/test/AST/ByteCode/cxx98.cpp +++ b/clang/test/AST/ByteCode/cxx98.cpp @@ -6,7 +6,7 @@ namespace IntOrEnum { const int k = 0; const int &p = k; // both-note {{declared here}} - template<int n> struct S {}; + template<int n> struct S {}; // both-note {{template parameter is declared here}} S<p> s; // both-error {{not an integral constant expression}} \ // both-note {{read of variable 'p' of non-integral, non-enumeration type 'const int &'}} } diff --git a/clang/test/AST/ByteCode/records.cpp b/clang/test/AST/ByteCode/records.cpp index 48cf811..fa8f850 100644 --- a/clang/test/AST/ByteCode/records.cpp +++ b/clang/test/AST/ByteCode/records.cpp @@ -1738,7 +1738,7 @@ namespace CtorOfInvalidClass { // both-error {{must be initialized by a constant expression}} #if __cplusplus >= 202002L - template <typename T, auto Q> + template <typename T, auto Q>// both-note {{template parameter is declared here}} concept ReferenceOf = Q; /// This calls a valid and constexpr copy constructor of InvalidCtor, /// but should still be rejected. diff --git a/clang/test/CXX/basic/basic.lookup/basic.lookup.unqual/p7.cpp b/clang/test/CXX/basic/basic.lookup/basic.lookup.unqual/p7.cpp index 9632fda..fc4e359 100644 --- a/clang/test/CXX/basic/basic.lookup/basic.lookup.unqual/p7.cpp +++ b/clang/test/CXX/basic/basic.lookup/basic.lookup.unqual/p7.cpp @@ -33,5 +33,6 @@ namespace test1 { // specifiers. namespace test2 { template <class T> struct bar {}; + // expected-note@-1 {{template parameter is declared here}} template <class T> struct foo : bar<foo> {}; // expected-error {{use of class template 'foo' requires template arguments}} expected-note {{template is declared here}} } diff --git a/clang/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x.cpp b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x.cpp index 5bb4708f..2a2b338 100644 --- a/clang/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x.cpp +++ b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x.cpp @@ -253,5 +253,5 @@ void P1957R2(void *a, int *b, Agg<int> *c, int Agg<int>::*d) { Agg<bool> tc = {c}; // expected-error {{cannot be narrowed}} expected-note {{}} Agg<bool> td = {d}; // expected-error {{cannot be narrowed}} expected-note {{}} } -template<bool> struct BoolParam {}; +template<bool> struct BoolParam {}; // expected-note {{template parameter is declared here}} BoolParam<&P1957R2> bp; // expected-error {{not allowed in a converted constant expression}} diff --git a/clang/test/CXX/drs/cwg0xx.cpp b/clang/test/CXX/drs/cwg0xx.cpp index 805be67..c94bc02 100644 --- a/clang/test/CXX/drs/cwg0xx.cpp +++ b/clang/test/CXX/drs/cwg0xx.cpp @@ -806,6 +806,7 @@ namespace cwg49 { // cwg49: 2.8 // since-cxx17-error@#cwg49-c {{non-type template argument is not a constant expression}} // since-cxx17-note@#cwg49-c {{read of non-constexpr variable 'q' is not allowed in a constant expression}} // since-cxx17-note@#cwg49-q {{declared here}} + // since-cxx17-note@#cwg49-A {{template parameter is declared here}} } // namespace cwg49 namespace cwg50 { // cwg50: 2.7 @@ -1018,9 +1019,9 @@ namespace cwg62 { // cwg62: 2.9 struct A { struct { int n; } b; }; - template<typename T> struct X {}; - template<typename T> T get() { return get<T>(); } - template<typename T> int take(T) { return 0; } + template<typename T> struct X {}; // #cwg62-X + template<typename T> T get() { return get<T>(); } // #cwg62-get + template<typename T> int take(T) { return 0; } // #cwg62-take X<A> x1; A a = get<A>(); @@ -1034,22 +1035,27 @@ namespace cwg62 { // cwg62: 2.9 X<NoNameForLinkagePtr> x2; // cxx98-error@-1 {{template argument uses unnamed type}} + // cxx98-note@#cwg62-X {{template parameter is declared here}} // cxx98-note@#cwg62-unnamed {{unnamed type used in template argument was declared here}} X<const NoNameForLinkagePtr> x3; // cxx98-error@-1 {{template argument uses unnamed type}} + // cxx98-note@#cwg62-X {{template parameter is declared here}} // cxx98-note@#cwg62-unnamed {{unnamed type used in template argument was declared here}} NoNameForLinkagePtr p1 = get<NoNameForLinkagePtr>(); // cxx98-error@-1 {{template argument uses unnamed type}} + // cxx98-note@#cwg62-get {{template parameter is declared here}} // cxx98-note@#cwg62-unnamed {{unnamed type used in template argument was declared here}} - // cxx98-note@-3 {{while substituting explicitly-specified template arguments}} + // cxx98-note@-4 {{while substituting explicitly-specified template arguments}} NoNameForLinkagePtr p2 = get<const NoNameForLinkagePtr>(); // cxx98-error@-1 {{template argument uses unnamed type}} + // cxx98-note@#cwg62-get {{template parameter is declared here}} // cxx98-note@#cwg62-unnamed {{unnamed type used in template argument was declared here}} - // cxx98-note@-3 {{while substituting explicitly-specified template arguments}} + // cxx98-note@-4 {{while substituting explicitly-specified template arguments}} int n1 = take(noNameForLinkagePtr); // cxx98-error@-1 {{template argument uses unnamed type}} + // cxx98-note@#cwg62-take {{template parameter is declared here}} // cxx98-note@#cwg62-unnamed {{unnamed type used in template argument was declared here}} - // cxx98-note@-3 {{while substituting deduced template arguments}} + // cxx98-note@-4 {{while substituting deduced template arguments}} X<Danger> x4; @@ -1057,18 +1063,24 @@ namespace cwg62 { // cwg62: 2.9 struct NoLinkage {}; X<NoLinkage> a; // cxx98-error@-1 {{template argument uses local type }} + // cxx98-note@#cwg62-X {{template parameter is declared here}} X<const NoLinkage> b; // cxx98-error@-1 {{template argument uses local type }} + // cxx98-note@#cwg62-X {{template parameter is declared here}} get<NoLinkage>(); // cxx98-error@-1 {{template argument uses local type }} - // cxx98-note@-2 {{while substituting explicitly-specified template arguments}} + // cxx98-note@#cwg62-get {{template parameter is declared here}} + // cxx98-note@-3 {{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}} + // cxx98-note@#cwg62-get {{template parameter is declared here}} + // cxx98-note@-3 {{while substituting explicitly-specified template arguments}} X<void (*)(NoLinkage A::*)> c; // cxx98-error@-1 {{template argument uses local type }} + // cxx98-note@#cwg62-X {{template parameter is declared here}} X<int NoLinkage::*> d; // cxx98-error@-1 {{template argument uses local type }} + // cxx98-note@#cwg62-X {{template parameter is declared here}} } } // namespace cwg62 @@ -1135,10 +1147,11 @@ namespace cwg69 { // cwg69: 9 extern template void f<char>(); // cxx98-error@-1 {{extern templates are a C++11 extension}} // expected-error@-2 {{explicit instantiation declaration of 'f' with internal linkage}} - template<void(*)()> struct Q {}; + template<void(*)()> struct Q {}; // #cwg69-Q Q<&f<int> > q; // cxx98-error@-1 {{non-type template argument referring to function 'f<int>' with internal linkage is a C++11 extension}} // cxx98-note@#cwg69-f {{non-type template argument refers to function here}} + // cxx98-note@#cwg69-Q {{template parameter is declared here}} } // namespace cwg69 namespace cwg70 { // cwg70: 2.7 diff --git a/clang/test/CXX/drs/cwg10xx.cpp b/clang/test/CXX/drs/cwg10xx.cpp index c5b96c4..10ee505 100644 --- a/clang/test/CXX/drs/cwg10xx.cpp +++ b/clang/test/CXX/drs/cwg10xx.cpp @@ -43,6 +43,7 @@ namespace cwg1004 { // cwg1004: 5 template<class T, template<class> class U = T::template A> struct Third { }; // expected-error@-1 {{is a constructor name}} // expected-note@#cwg1004-t {{in instantiation of default argument}} + // expected-note@-3 {{template parameter is declared here}} Third<A<int> > t; // #cwg1004-t } // namespace cwg1004 diff --git a/clang/test/CXX/drs/cwg13xx.cpp b/clang/test/CXX/drs/cwg13xx.cpp index ad6ee01..0fae345 100644 --- a/clang/test/CXX/drs/cwg13xx.cpp +++ b/clang/test/CXX/drs/cwg13xx.cpp @@ -180,6 +180,7 @@ namespace cwg1315 { // cwg1315: partial // dependent type of T::value is not the same as 'int'. // A core issue will be opened to decide what is supposed to happen here. template <typename T, int I> struct C; + // expected-note@-1 {{template parameter is declared here}} template <typename T> struct C<T, T::value>; // expected-error@-1 {{type of specialized non-type template argument depends on a template parameter of the partial specialization}} } // namespace cwg1315 diff --git a/clang/test/CXX/drs/cwg18xx.cpp b/clang/test/CXX/drs/cwg18xx.cpp index 9948075..0d46eab 100644 --- a/clang/test/CXX/drs/cwg18xx.cpp +++ b/clang/test/CXX/drs/cwg18xx.cpp @@ -26,6 +26,7 @@ S<i> V; // #cwg1801-S-i // cxx98-14-error@-1 {{non-type template argument does not refer to any declaration}} // cxx98-14-note@#cwg1801-S {{template parameter is declared here}} // cxx17-error@#cwg1801-S-i {{non-type template argument refers to subobject '.i'}} +// cxx17-note@#cwg1801-S {{template parameter is declared here}} } // namespace cwg1801 namespace cwg1802 { // cwg1802: 3.1 diff --git a/clang/test/CXX/drs/cwg1xx.cpp b/clang/test/CXX/drs/cwg1xx.cpp index c9dce77..e15a225 100644 --- a/clang/test/CXX/drs/cwg1xx.cpp +++ b/clang/test/CXX/drs/cwg1xx.cpp @@ -26,18 +26,22 @@ namespace cwg100 { // cwg100: 2.7 // cxx98-14-error@#cwg100-a {{non-type template argument does not refer to any declaration}} // cxx98-14-note@#cwg100-A {{template parameter is declared here}} // since-cxx17-error@#cwg100-a {{pointer to string literal is not allowed in a template argument}} + // since-cxx17-note@#cwg100-A {{template parameter is declared here}} B<"bar"> b; // #cwg100-b // cxx98-14-error@#cwg100-b {{non-type template argument does not refer to any declaration}} // cxx98-14-note@#cwg100-B {{template parameter is declared here}} // since-cxx17-error@#cwg100-b {{reference to string literal is not allowed in a template argument}} + // since-cxx17-note@#cwg100-B {{template parameter is declared here}} C<"baz"> c; // #cwg100-c // cxx98-14-error@#cwg100-c {{non-type template argument does not refer to any declaration}} // cxx98-14-note@#cwg100-C {{template parameter is declared here}} // since-cxx17-error@#cwg100-c {{pointer to subobject of string literal is not allowed in a template argument}} + // since-cxx17-note@#cwg100-C {{template parameter is declared here}} D<*"quux"> d; // #cwg100-d // cxx98-14-error@#cwg100-d {{non-type template argument does not refer to any declaration}} // cxx98-14-note@#cwg100-D {{template parameter is declared here}} // since-cxx17-error@#cwg100-d {{reference to subobject of string literal is not allowed in a template argument}} + // since-cxx17-note@#cwg100-D {{template parameter is declared here}} } // namespace cwg100 namespace cwg101 { // cwg101: 3.5 @@ -152,15 +156,17 @@ namespace cwg112 { // cwg112: 3.1 volatile T a2[1] = {}; const Arr a3 = {}; // #cwg112-a3 volatile Arr a4 = {}; - template<const volatile T*> struct X {}; + template<const volatile T*> struct X {}; // #cwg112-X // FIXME: Test this somehow in C++11 and on. X<a1> x1; // cxx98-error@-1 {{non-type template argument referring to object 'a1' with internal linkage is a C++11 extension}} // cxx98-note@#cwg112-a1 {{non-type template argument refers to object here}} + // cxx98-note@#cwg112-X {{template parameter is declared here}} X<a2> x2; X<a3> x3; // cxx98-error@-1 {{non-type template argument referring to object 'a3' with internal linkage is a C++11 extension}} // cxx98-note@#cwg112-a3 {{non-type template argument refers to object here}} + // cxx98-note@#cwg112-X {{template parameter is declared here}} X<a4> x4; } // namespace cwg112 @@ -634,7 +640,7 @@ namespace example3 { struct Base { private: static const int i = 10; // #cwg138-ex3-Base-i - + public: struct Data; // Elaborated type specifier is not the sole constituent of declaration, @@ -648,7 +654,7 @@ public: }; }; struct Data { - void f() { + void f() { int i2 = Base::i; // expected-error@-1 {{'i' is a private member of 'cwg138::example3::Base'}} // expected-note@#cwg138-ex3-Base-i {{declared private here}} @@ -1308,8 +1314,8 @@ namespace cwg184 { // cwg184: 2.7 template<template<typename TT> class T> void A<T>::f() { // #cwg184-T T<> t; - // expected-error@-1 {{too few template arguments for template template parameter 'T'}} - // expected-note@#cwg184-T {{template is declared here}} + // expected-error@-1 {{missing template argument for template parameter}} + // expected-note@#cwg184-T {{template parameter is declared here}} } template<template<typename TT = char> class T> void A<T>::g() { diff --git a/clang/test/CXX/drs/cwg20xx.cpp b/clang/test/CXX/drs/cwg20xx.cpp index 141a101..fd31a51f 100644 --- a/clang/test/CXX/drs/cwg20xx.cpp +++ b/clang/test/CXX/drs/cwg20xx.cpp @@ -27,7 +27,7 @@ int b = __builtin_addressof(b2)->foo; // cwg2009: na namespace cwg2026 { // cwg2026: 11 - template<int> struct X {}; + template<int> struct X {}; // #cwg2026-X const int a = a + 1; // #cwg2026-a // expected-warning@-1 {{variable 'a' is uninitialized when used within its own initialization}} @@ -35,9 +35,11 @@ namespace cwg2026 { // cwg2026: 11 // cxx98-error@-1 {{non-type template argument of type 'int' is not an integral constant expression}} // cxx98-note@-2 {{initializer of 'a' is not a constant expression}} // cxx98-note@#cwg2026-a {{declared here}} + // cxx98-note@#cwg2026-X {{template parameter is declared here}} // since-cxx11-error@#cwg2026-xa {{non-type template argument is not a constant expression}} // since-cxx11-note@#cwg2026-xa {{initializer of 'a' is not a constant expression}} // since-cxx11-note@#cwg2026-a {{declared here}} + // since-cxx11-note@#cwg2026-X {{template parameter is declared here}} #if __cplusplus >= 201103L constexpr int b = b; @@ -65,9 +67,11 @@ namespace cwg2026 { // cwg2026: 11 // cxx98-error@-1 {{non-type template argument of type 'int' is not an integral constant expression}} // cxx98-note@-2 {{initializer of 'e' is not a constant expression}} // cxx98-note@#cwg2026-e {{declared here}} + // cxx98-note@#cwg2026-X {{template parameter is declared here}} // since-cxx11-error@#cwg2026-xe {{non-type template argument is not a constant expression}} // since-cxx11-note@#cwg2026-xe {{initializer of 'e' is not a constant expression}} // since-cxx11-note@#cwg2026-e {{declared here}} + // since-cxx11-note@#cwg2026-X {{template parameter is declared here}} #if __cplusplus >= 201103L static constexpr int f = f; @@ -149,7 +153,7 @@ namespace cwg2076 { // cwg2076: 13 operator string_view() const; }; - void foo(const string &); // #cwg2076-foo + void foo(const string &); // #cwg2076-foo void bar(string_view); // #cwg2076-bar void func(const string &arg) { @@ -429,7 +433,7 @@ int f() return 0; } } // namespace GH42233 -} // namespace cwg2091 +} // namespace cwg2091 namespace cwg2094 { // cwg2094: 5 struct A { int n; }; diff --git a/clang/test/CXX/drs/cwg21xx.cpp b/clang/test/CXX/drs/cwg21xx.cpp index 42a7c4d..97bf320 100644 --- a/clang/test/CXX/drs/cwg21xx.cpp +++ b/clang/test/CXX/drs/cwg21xx.cpp @@ -24,7 +24,7 @@ namespace std { } namespace cwg2100 { // cwg2100: 12 - template<const int *P, bool = true> struct X {}; + template<const int *P, bool = true> struct X {}; // #cwg2100-X template<typename T> struct A { static const int n = 1; int f() { @@ -35,6 +35,7 @@ namespace cwg2100 { // cwg2100: 12 return X<&n>::n; // ok, value-dependent // cxx98-14-error@-1 {{non-type template argument refers to object 'n' that does not have linkage}} // cxx98-14-note@#cwg2100-n {{non-type template argument refers to object here}} + // cxx98-14-note@#cwg2100-X {{template parameter is declared here}} } }; template<const int *P> struct X<P> { diff --git a/clang/test/CXX/drs/cwg3xx.cpp b/clang/test/CXX/drs/cwg3xx.cpp index bbd87c0..423322a 100644 --- a/clang/test/CXX/drs/cwg3xx.cpp +++ b/clang/test/CXX/drs/cwg3xx.cpp @@ -317,18 +317,20 @@ namespace cwg319 { // cwg319: no typedef int (*pa)[n1]; pa parr; // ok, type has linkage despite using 'n1' - template<typename> struct X {}; + template<typename> struct X {}; // #cwg319-X void f() { struct A { int n; }; extern A a; // FIXME: ill-formed X<A> xa; // cxx98-error@-1 {{template argument uses local type 'A'}} + // cxx98-note@#cwg319-X {{template parameter is declared here}} typedef A B; extern B b; // FIXME: ill-formed X<B> xb; // cxx98-error@-1 {{template argument uses local type 'A'}} + // cxx98-note@#cwg319-X {{template parameter is declared here}} const int n = 1; typedef int (*C)[n]; @@ -997,6 +999,7 @@ namespace cwg354 { // cwg354: 3.1 c++11 // since-cxx17-note@#cwg354-ptr_mem {{template parameter is declared here}} ptr_mem<(int S::*)0> m1; // cxx98-error@-1 {{non-type template argument is not a pointer to member constant}} + // cxx98-note@#cwg354-ptr_mem {{template parameter is declared here}} ptr_mem<(float S::*)0> m2; // #cwg354-m2 // cxx98-error@#cwg354-m2 {{non-type template argument of type 'float S::*' cannot be converted to a value of type 'int S::*'}} // cxx98-note@#cwg354-ptr_mem {{template parameter is declared here}} @@ -1502,7 +1505,7 @@ namespace cwg389 { // cwg389: no typedef struct {} const C; // #cwg389-C typedef enum {} const D; // #cwg389-D }; - template<typename> struct T {}; + template<typename> struct T {}; // #cwg389-T struct WithLinkage1 {}; enum WithLinkage2 {}; @@ -1543,18 +1546,23 @@ namespace cwg389 { // cwg389: no typedef T<WithoutLinkage1> BadArg1; // expected-error@-1 {{template argument uses unnamed type}} + // expected-note@#cwg389-T {{template parameter is declared here}} // expected-note@#cwg389-no-link-1 {{unnamed type used in template argument was declared here}} typedef T<WithoutLinkage2> BadArg2; // expected-error@-1 {{template argument uses unnamed type}} + // expected-note@#cwg389-T {{template parameter is declared here}} // expected-note@#cwg389-no-link-2 {{unnamed type used in template argument was declared here}} typedef T<WithoutLinkage3> BadArg3; // expected-error@-1 {{template argument uses unnamed type}} + // expected-note@#cwg389-T {{template parameter is declared here}} // expected-note@#cwg389-C {{unnamed type used in template argument was declared here}} typedef T<WithoutLinkage4> BadArg4; // expected-error@-1 {{template argument uses unnamed type}} + // expected-note@#cwg389-T {{template parameter is declared here}} // expected-note@#cwg389-D {{unnamed type used in template argument was declared here}} typedef T<WithoutLinkage5> BadArg5; // expected-error@-1 {{template argument uses unnamed type}} + // expected-note@#cwg389-T {{template parameter is declared here}} // expected-note@#cwg389-C {{unnamed type used in template argument was declared here}} #endif diff --git a/clang/test/CXX/drs/cwg4xx.cpp b/clang/test/CXX/drs/cwg4xx.cpp index 8497f97..e5c9efa 100644 --- a/clang/test/CXX/drs/cwg4xx.cpp +++ b/clang/test/CXX/drs/cwg4xx.cpp @@ -52,12 +52,15 @@ namespace cwg401 { // cwg401: 2.8 // expected-error@#cwg401-A {{'type' is a private member of 'cwg401::C'}} // expected-note@#cwg402-friend-A-C {{in instantiation of default argument for 'A<C>' required here}} // expected-note@#cwg402-C-type {{implicitly declared private here}} + // expected-note@#cwg401-A {{template parameter is declared here}} // expected-error@#cwg401-A {{'type' is a protected member of 'cwg401::B'}} // expected-note@#cwg402-b {{in instantiation of default argument for 'A<B>' required here}} // expected-note@#cwg402-B-type {{declared protected here}} + // expected-note@#cwg401-A {{template parameter is declared here}} // expected-error@#cwg401-A {{'type' is a private member of 'cwg401::D'}} // expected-note@#cwg402-d {{in instantiation of default argument for 'A<D>' required here}} // expected-note@#cwg402-D-type {{implicitly declared private here}} + // expected-note@#cwg401-A {{template parameter is declared here}} class B { protected: typedef int type; // #cwg402-B-type @@ -89,8 +92,9 @@ namespace cwg401 { // cwg401: 2.8 // to not treat the default template argument as a SFINAE context in C++98. template<class T, class U = typename T::type> void f(T) {} // #cwg402-f // cxx98-error@-1 {{default template arguments for a function template are a C++11 extension}} - // cxx98-error@-2 {{'type' is a protected member of 'cwg401::B'}} - // cxx98-note@-3 {{in instantiation of default argument for 'f<B>' required here}} + // cxx98-note@-2 {{template parameter is declared here}} + // cxx98-error@-3 {{'type' is a protected member of 'cwg401::B'}} + // cxx98-note@-4 {{in instantiation of default argument for 'f<B>' required here}} // cxx98-note@#cwg402-f-b {{while substituting deduced template arguments into function template 'f' [with T = B, U = (no value)]}} // cxx98-note@#cwg402-B-type {{declared protected here}} void g(B b) { f(b); } // #cwg402-f-b @@ -645,15 +649,17 @@ namespace cwg431 { // cwg431: 2.8 } // namespace cwg431 namespace cwg432 { // cwg432: 3.0 - template<typename T> struct A {}; + template<typename T> struct A {}; // #cwg432-A template<typename T> struct B : A<B> {}; // expected-error@-1 {{use of class template 'B' requires template arguments}} - // expected-note@-2 {{template is declared here}} + // expected-note@#cwg432-A {{template parameter is declared here}} + // expected-note@-3 {{template is declared here}} template<typename T> struct C : A<C<T> > {}; #if __cplusplus >= 201103L template<typename T> struct D : decltype(A<D>()) {}; // since-cxx11-error@-1 {{use of class template 'D' requires template arguments}} - // since-cxx11-note@-2 {{template is declared here}} + // since-cxx11-note@#cwg432-A {{template parameter is declared here}} + // since-cxx11-note@-3 {{template is declared here}} #endif } // namespace cwg432 @@ -1386,6 +1392,7 @@ namespace cwg487 { // cwg487: 2.7 namespace cwg488 { // cwg488: 2.9 c++11 template <typename T> void f(T); + // cxx98-note@-1 {{template parameter is declared here}} void f(int); void g() { // FIXME: It seems CWG thought this should be a SFINAE failure prior to diff --git a/clang/test/CXX/drs/cwg6xx.cpp b/clang/test/CXX/drs/cwg6xx.cpp index 11eb0bf..c17e1e2 100644 --- a/clang/test/CXX/drs/cwg6xx.cpp +++ b/clang/test/CXX/drs/cwg6xx.cpp @@ -79,10 +79,11 @@ namespace cwg602 { // cwg602: 2.7 } // namespace cwg602 namespace cwg603 { // cwg603: 3.1 - template<unsigned char> struct S {}; + template<unsigned char> struct S {}; // #cwg603-S typedef S<'\001'> S1; typedef S<(1ul << __CHAR_BIT__) + 1> S1; // since-cxx11-error@-1 {{non-type template argument evaluates to 257, which cannot be narrowed to type 'unsigned char'}} + // since-cxx11-note@#cwg603-S {{template parameter is declared here}} } // namespace cwg603 // cwg604: na diff --git a/clang/test/CXX/expr/expr.const/p3-0x.cpp b/clang/test/CXX/expr/expr.const/p3-0x.cpp index 3eedef3..f40e1af 100644 --- a/clang/test/CXX/expr/expr.const/p3-0x.cpp +++ b/clang/test/CXX/expr/expr.const/p3-0x.cpp @@ -4,7 +4,7 @@ // A converted constant expression of type T is a core constant expression, int nonconst = 8; // expected-note 3 {{here}} enum NonConstE : unsigned char { NCE = nonconst }; // expected-error {{enumerator value is not a constant expression}} expected-note {{read of non-const}} -template<int = nonconst> struct NonConstT {}; // expected-error {{non-type template argument is not a constant expression}} expected-note {{read of non-const}} +template<int = nonconst> struct NonConstT {}; // expected-error {{non-type template argument is not a constant expression}} expected-note {{read of non-const}} expected-note {{template parameter is declared here}} void NonConstF() { switch (nonconst) { case nonconst: // expected-error {{case value is not a constant expression}} expected-note {{read of non-const}} @@ -66,7 +66,7 @@ enum class EEE : unsigned short { e = 123456, // expected-error {{enumerator value evaluates to 123456, which cannot be narrowed to type 'unsigned short'}} f = -3 // expected-error {{enumerator value evaluates to -3, which cannot be narrowed to type 'unsigned short'}} }; -template<unsigned char> using A = int; // cxx17-note 2{{template parameter is declared here}} +template<unsigned char> using A = int; // expected-note 4{{template parameter is declared here}} using Int = A<E6>; using Int = A<EE::EE32>; // expected-error {{not implicitly convertible}} @@ -79,7 +79,8 @@ using Int = A<-3>; // expected-error {{template argument evaluates to -3, which // integral conversions as well as boolean conversions. // FIXME: Per core issue 1407, this is not correct. template<typename T, T v> struct Val { static constexpr T value = v; }; -// cxx17-note@-1 2{{template parameter is declared here}} +// cxx17-note@-1 1{{template parameter is declared here}} +// expected-note@-2 2{{template parameter is declared here}} static_assert(Val<bool, E1>::value == 1, ""); // ok static_assert(Val<bool, '\0'>::value == 0, ""); // ok static_assert(Val<bool, U'\1'>::value == 1, ""); // ok diff --git a/clang/test/CXX/expr/expr.prim/expr.prim.req/type-requirement.cpp b/clang/test/CXX/expr/expr.prim/expr.prim.req/type-requirement.cpp index 5433cfb..2572e76 100644 --- a/clang/test/CXX/expr/expr.prim/expr.prim.req/type-requirement.cpp +++ b/clang/test/CXX/expr/expr.prim/expr.prim.req/type-requirement.cpp @@ -77,7 +77,7 @@ using r2i3 = r2<int, int>; // expected-error{{constraints not satisfied for clas namespace ns2 { template<typename T, typename U> struct identity {}; - template<typename... Ts> requires requires { typename identity<Ts...>; } // expected-note 2{{because 'typename identity<Ts...>' would be invalid: too few template arguments for class template 'identity'}} + template<typename... Ts> requires requires { typename identity<Ts...>; } // expected-note 2{{because 'typename identity<Ts...>' would be invalid: missing template argument for template parameter}} struct r4 {}; using r4i1 = r4<int>; // expected-error{{constraints not satisfied for class template 'r4' [with Ts = <int>]}} diff --git a/clang/test/CXX/temp/temp.arg/temp.arg.nontype/p1-11.cpp b/clang/test/CXX/temp/temp.arg/temp.arg.nontype/p1-11.cpp index 692958e..332f69b 100644 --- a/clang/test/CXX/temp/temp.arg/temp.arg.nontype/p1-11.cpp +++ b/clang/test/CXX/temp/temp.arg/temp.arg.nontype/p1-11.cpp @@ -9,7 +9,7 @@ template<int *ip> struct IP { // expected-note 6 {{template parameter is declar IP<ip> *ip2; }; -template<int &ip> struct IR {}; +template<int &ip> struct IR {}; // expected-note {{template parameter is declared here}} constexpr std::nullptr_t get_nullptr() { return nullptr; } diff --git a/clang/test/CXX/temp/temp.arg/temp.arg.nontype/p1.cpp b/clang/test/CXX/temp/temp.arg/temp.arg.nontype/p1.cpp index 73c7c75..b6a0fdd 100644 --- a/clang/test/CXX/temp/temp.arg/temp.arg.nontype/p1.cpp +++ b/clang/test/CXX/temp/temp.arg/temp.arg.nontype/p1.cpp @@ -31,16 +31,16 @@ namespace non_type_tmpl_param { // omitted if the name refers to a function or array and shall be omitted // if the corresopnding template-parameter is a reference; or namespace addr_of_obj_or_func { - template <int* p> struct X0 { }; // expected-note 5{{here}} + template <int* p> struct X0 { }; // expected-note 5{{here}} cxx17-note 2{{here}} #if __cplusplus >= 201103L // precxx17-note@-2 2{{template parameter is declared here}} #endif - template <int (*fp)(int)> struct X1 { }; // cxx17-note {{here}} + template <int (*fp)(int)> struct X1 { }; // cxx17-note {{here}} precxx17-note{{here}} #if __cplusplus <= 199711L // precxx17-note@-2 {{here}} #endif - template <int &p> struct X2 { }; // expected-note 4{{here}} + template <int &p> struct X2 { }; // expected-note 5{{here}} template <const int &p> struct X2k { }; // expected-note {{here}} template <int (&fp)(int)> struct X3 { }; // expected-note 4{{here}} @@ -180,6 +180,7 @@ namespace addr_of_obj_or_func { namespace bad_args { template <int* N> struct X0 { }; // precxx17-note 4{{template parameter is declared here}} + // cxx17-note@-1 3{{template parameter is declared here}} int i = 42; X0<&i + 2> x0a; // precxx17-error{{non-type template argument does not refer to any declaration}} \ cxx17-error {{non-type template argument is not a constant expression}} \ diff --git a/clang/test/CXX/temp/temp.arg/temp.arg.nontype/p5.cpp b/clang/test/CXX/temp/temp.arg/temp.arg.nontype/p5.cpp index 4b93d86..d35a298 100644 --- a/clang/test/CXX/temp/temp.arg/temp.arg.nontype/p5.cpp +++ b/clang/test/CXX/temp/temp.arg/temp.arg.nontype/p5.cpp @@ -49,7 +49,7 @@ namespace pointer_to_object_parameters { operator int() const; }; - template<X const *Ptr> struct A2; // expected-note 0-1{{template parameter is declared here}} + template<X const *Ptr> struct A2; // expected-note 1-2{{template parameter is declared here}} X *X_ptr; // expected-note 0-1{{declared here}} X an_X; diff --git a/clang/test/CXX/temp/temp.arg/temp.arg.template/p3-0x.cpp b/clang/test/CXX/temp/temp.arg/temp.arg.template/p3-0x.cpp index 3caed04..2638bef 100644 --- a/clang/test/CXX/temp/temp.arg/temp.arg.template/p3-0x.cpp +++ b/clang/test/CXX/temp/temp.arg/temp.arg.template/p3-0x.cpp @@ -20,39 +20,39 @@ eval<E<int, float>> eE; // expected-error{{implicit instantiation of undefined t template< template <int ...N> // expected-error {{cannot be narrowed from type 'int' to 'short'}} // expected-error@-1 {{conversion from 'int' to 'void *' is not allowed in a converted constant expression}} - class TT // expected-note 2{{previous template template parameter is here}} + class TT // expected-note 2{{template parameter is declared here}} > struct X0 { }; template<int I, int J, int ...Rest> struct X0a; template<int ...Rest> struct X0b; template<int I, long J> struct X0c; -template<int I, short J> struct X0d; -template<int I, void *J> struct X0e; // expected-note{{template parameter is declared here}} +template<int I, short J> struct X0d; // expected-note {{template parameter is declared here}} +template<int I, void *J> struct X0e; // expected-note {{template parameter is declared here}} X0<X0a> inst_x0a; X0<X0b> inst_x0b; X0<X0c> inst_x0c; -X0<X0d> inst_x0d; // expected-note {{has different template parameters}} -X0<X0e> inst_x0e; // expected-note{{template template argument has different template parameters than its corresponding template template parameter}} +X0<X0d> inst_x0d; // expected-note {{template template argument is incompatible}} +X0<X0e> inst_x0e; // expected-note {{template template argument is incompatible}} template<typename T, template <T ...N> // expected-error {{conversion from 'short' to 'void *' is not allowed in a converted constant expression}} // expected-error@-1 {{cannot be narrowed from type 'int' to 'short'}} - class TT // expected-note 2{{previous template template parameter is here}} + class TT // expected-note 2{{template parameter is declared here}} > struct X1 { }; template<int I, int J, int ...Rest> struct X1a; template<long I, long ...Rest> struct X1b; template<short I, short J> struct X1c; -template<short I, long J> struct X1d; -template<short I, void *J> struct X1e; // expected-note{{template parameter is declared here}} +template<short I, long J> struct X1d; // expected-note {{template parameter is declared here}} +template<short I, void *J> struct X1e; // expected-note {{template parameter is declared here}} X1<int, X1a> inst_x1a; X1<long, X1b> inst_x1b; X1<short, X1c> inst_x1c; X1<short, X1d> inst_sx1d; -X1<int, X1d> inst_ix1d; // expected-note {{has different template parameters}} -X1<short, X1e> inst_x1e; // expected-note {{has different template parameters}} +X1<int, X1d> inst_ix1d; // expected-note {{template template argument is incompatible}} +X1<short, X1e> inst_x1e; // expected-note {{template template argument is incompatible}} template <int> class X2; // expected-note{{template is declared here}} \ // expected-note{{template is declared here}} diff --git a/clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp b/clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp index 342ffba..5570a7f 100644 --- a/clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp +++ b/clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp @@ -13,12 +13,12 @@ template<F> struct W { }; // #W S1<X> s11; S1<Y> s12; // expected-error@-1 {{template template argument 'Y' is more constrained than template template parameter 'P'}} -// expected-note@#S1 {{'P' declared here}} +// expected-note@#S1 {{template parameter is declared here}} // expected-note@#Y {{'Y' declared here}} S1<Z> s13; S1<W> s14; // expected-error@-1 {{template template argument 'W' is more constrained than template template parameter 'P'}} -// expected-note@#S1 {{'P' declared here}} +// expected-note@#S1 {{template parameter is declared here}} // expected-note@#W {{'W' declared here}} // expected-note@#F 1-2{{similar constraint expressions not considered equivalent}} // expected-note@#C 1-2{{similar constraint}} @@ -43,12 +43,12 @@ template<template<typename T> requires C<T> class P> struct S4 { }; // #S4 S4<X> s41; S4<Y> s42; // expected-error@-1 {{template template argument 'Y' is more constrained than template template parameter 'P'}} -// expected-note@#S4 {{'P' declared here}} +// expected-note@#S4 {{template parameter is declared here}} // expected-note@#Y {{'Y' declared here}} S4<Z> s43; S4<W> s44; // expected-error@-1 {{template template argument 'W' is more constrained than template template parameter 'P'}} -// expected-note@#S4 {{'P' declared here}} +// expected-note@#S4 {{template parameter is declared here}} // expected-note@#W {{'W' declared here}} template<template<typename T> requires C<T> typename U> struct S5 { 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 650f858..65f3e17 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 @@ -1,5 +1,5 @@ // RUN: %clang_cc1 -fsyntax-only -verify -Wvla %s -// RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s +// RUN: %clang_cc1 -fsyntax-only -verify=expected,cxx98 -std=c++98 %s // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s template<class T> struct A { @@ -13,7 +13,8 @@ template<typename T> struct B { }; B<function> b; // expected-note{{instantiation of}} -template <typename T> int f0(void *, const T&); // expected-note{{candidate template ignored: substitution failure}} +template <typename T> // #f0-temphead +int f0(void *, const T&); // expected-note{{candidate template ignored: substitution failure}} enum {e}; // expected-note@-1 {{unnamed type used in template argument was declared here}} @@ -22,6 +23,7 @@ void test_f0(int n) { // #here #if __cplusplus <= 199711L // expected-warning@-2 {{template argument uses unnamed type}} // expected-note@-3 {{while substituting deduced template arguments}} + // expected-note@#f0-temphead {{template parameter is declared here}} #endif int vla[n]; // expected-warning {{variable length arrays in C++ are a Clang extension}} @@ -33,9 +35,9 @@ void test_f0(int n) { // #here } namespace N0 { - template <typename R, typename A1> void f0(R (*)(A1)); - template <typename T> int f1(T); - template <typename T, typename U> int f1(T, U); + template <typename R, typename A1> void f0(R (*)(A1)); // #f0 + template <typename T> int f1(T); // #f1-1 + template <typename T, typename U> int f1(T, U); // #f1-2 enum {e1}; #if __cplusplus <= 199711L // expected-note@-2 2{{unnamed type used in template argument was declared here}} @@ -51,7 +53,7 @@ namespace N0 { // expected-note@-2 {{unnamed type used in template argument was declared here}} #endif - template<typename T> struct X; + template<typename T> struct X; // cxx98-note {{template parameter is declared here}} template<typename T> struct X<T*> { }; void f() { @@ -59,24 +61,28 @@ namespace N0 { #if __cplusplus <= 199711L // expected-warning@-2 {{template argument uses unnamed type}} // expected-note@-3 {{while substituting deduced template arguments}} + // expected-note@#f0 {{template parameter is declared here}} #endif &f1<__typeof__(e1)>); #if __cplusplus <= 199711L // expected-warning@-2 {{template argument uses unnamed type}} // expected-note@-3 {{while substituting explicitly-specified template arguments}} + // expected-note@#f1-1 {{template parameter is declared here}} #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}} + // expected-note@#f1-2 {{template parameter is declared here}} #endif f1(e2); #if __cplusplus <= 199711L // expected-warning@-2 {{template argument uses unnamed type}} // expected-note@-3 {{while substituting deduced template arguments}} + // expected-note@#f1-1 {{template parameter is declared here}} #endif f1(e2); diff --git a/clang/test/CXX/temp/temp.decls/temp.class.spec/p8-1y.cpp b/clang/test/CXX/temp/temp.decls/temp.class.spec/p8-1y.cpp index 388a80e..cf01e40 100644 --- a/clang/test/CXX/temp/temp.decls/temp.class.spec/p8-1y.cpp +++ b/clang/test/CXX/temp/temp.decls/temp.class.spec/p8-1y.cpp @@ -25,7 +25,7 @@ template<typename Outer> struct X { template<typename Inner> static int y<Outer>; // expected-error 3{{cannot be deduced}} expected-note 3{{'Inner'}} template<typename Inner> static int y<Inner>; // expected-error {{does not specialize}} - template<typename, int> static int z; + template<typename, int> static int z; // expected-note {{template parameter is declared here}} template<Outer N> static int z<int, N>; // expected-error {{not implicitly convertible}} }; template<typename Outer> template<typename Inner> int X<Outer>::y<Outer>; // expected-error {{cannot be deduced}} expected-note {{'Inner'}} @@ -33,4 +33,4 @@ template<typename Outer> template<typename Inner> int X<Outer>::y<Inner>; // exp template<> template<typename Inner> int X<int>::y<Inner>; // expected-error {{does not specialize}} expected-note {{instantiation of}} X<int> xi; -X<int*> xf; // expected-note {{instantiation of}} +X<int*> xf; // expected-note 2{{instantiation of}} diff --git a/clang/test/CXX/temp/temp.decls/temp.variadic/fixed-expansion.cpp b/clang/test/CXX/temp/temp.decls/temp.variadic/fixed-expansion.cpp index ab4c663d..cab5c96 100644 --- a/clang/test/CXX/temp/temp.decls/temp.variadic/fixed-expansion.cpp +++ b/clang/test/CXX/temp/temp.decls/temp.variadic/fixed-expansion.cpp @@ -14,10 +14,10 @@ struct is_same<T, T> { }; namespace ExpandIntoFixed { - template<typename T, - typename U, - typename V = pair<T, U>, - typename W = V*> + template<typename T, + typename U, + typename V = pair<T, U>, + typename W = V*> class X0 { }; template<typename ...Ts> @@ -26,24 +26,24 @@ namespace ExpandIntoFixed { typedef X0<Ts...> type; }; - static_assert(is_same<X1<int, int>::type, + static_assert(is_same<X1<int, int>::type, X0<int, int, pair<int, int>, pair<int, int>*>>::value, "fails with two default arguments"); - static_assert(is_same<X1<int, int, float>::type, + static_assert(is_same<X1<int, int, float>::type, X0<int, int, float, float*>>::value, "fails with one default argument"); - static_assert(is_same<X1<int, int, float, double>::type, + static_assert(is_same<X1<int, int, float, double>::type, X0<int, int, float, double>>::value, "fails with no default arguments"); } namespace ExpandIntoFixedShifted { - template<typename T, - typename U, - typename V = pair<T, U>, - typename W = V*> + template<typename T, + typename U, + typename V = pair<T, U>, + typename W = V*> class X0 { }; template<typename ...Ts> @@ -52,15 +52,15 @@ namespace ExpandIntoFixedShifted { typedef X0<char, Ts...> type; }; - static_assert(is_same<X1<int>::type, + static_assert(is_same<X1<int>::type, X0<char, int, pair<char, int>, pair<char, int>*>>::value, "fails with two default arguments"); - static_assert(is_same<X1<int, float>::type, + static_assert(is_same<X1<int, float>::type, X0<char, int, float, float*>>::value, "fails with one default argument"); - static_assert(is_same<X1<int, float, double>::type, + static_assert(is_same<X1<int, float, double>::type, X0<char, int, float, double>>::value, "fails with no default arguments"); } @@ -76,11 +76,11 @@ namespace Deduction { } namespace PR9021a { - template<typename, typename> + template<typename, typename> struct A { }; template<typename ...T> - struct B { + struct B { A<T...> a1; }; @@ -93,9 +93,9 @@ namespace PR9021b { template<class, class> struct t2 { - + }; - + template<template<class...> class M> struct m { @@ -107,14 +107,14 @@ namespace PR9021b { } namespace PartialSpecialization { - template<typename T, typename U, typename V = U> - struct X0; // expected-note 2{{template is declared here}} + template<typename T, typename U, typename V = U> // expected-note {{template parameter is declared here}} + struct X0; // expected-note {{template is declared here}} template<typename ...Ts> struct X0<Ts...> { // expected-error {{class template partial specialization is not more specialized than the primary template}} }; - X0<int> x0i; // expected-error{{too few template arguments for class template 'X0'}} + X0<int> x0i; // expected-error{{missing template argument for template parameter}} X0<int, float> x0if; X0<int, float, double> x0ifd; } diff --git a/clang/test/CXX/temp/temp.decls/temp.variadic/multi-level-substitution.cpp b/clang/test/CXX/temp/temp.decls/temp.variadic/multi-level-substitution.cpp index 30e7c65..c6e6038 100644 --- a/clang/test/CXX/temp/temp.decls/temp.variadic/multi-level-substitution.cpp +++ b/clang/test/CXX/temp/temp.decls/temp.variadic/multi-level-substitution.cpp @@ -48,7 +48,7 @@ namespace PacksAtDifferentLevels { int check1[X<short, int>::Inner<tuple<pair<short, unsigned short>, pair<int, unsigned int>, pair<long, unsigned long>> - >::value == 1? 1 : -1]; + >::value == 1? 1 : -1]; template<unsigned ...Values> struct unsigned_tuple { }; template<typename ...Types> @@ -99,7 +99,7 @@ namespace PacksAtDifferentLevels { int check5[X2<short, int>::Inner<int(pair<short, unsigned short>, pair<int, unsigned int>, pair<long, unsigned long>) - >::value == 1? 1 : -1]; + >::value == 1? 1 : -1]; template<typename T, typename U> struct some_function_object { @@ -217,8 +217,8 @@ namespace ExpandingNonTypeTemplateParameters { template<typename ...Types> struct tuple_of_values { template<Types ...Values> // expected-error{{a non-type template parameter cannot have type 'float'}} \ - // expected-note{{template parameter is declared here}} - struct apply { // expected-note 2{{template is declared here}} + // expected-note 2{{template parameter is declared here}} + struct apply { // expected-note {{template is declared here}} typedef tuple<value_c<Types, Values>...> type; }; }; @@ -236,7 +236,7 @@ namespace ExpandingNonTypeTemplateParameters { tuple_of_values<int&, float&>::apply<i, i>::type tv2; // expected-error{{non-type template parameter of reference type 'float &' cannot bind to template argument of type 'int'}} - tuple_of_values<int&, float&>::apply<i>::type tv3; // expected-error{{too few template arguments for class template 'apply'}} + tuple_of_values<int&, float&>::apply<i>::type tv3; // expected-error{{missing template argument for template parameter}} tuple_of_values<int&, float&>::apply<i, f, i>::type tv4; // expected-error{{too many template arguments for class template 'apply'}} } diff --git a/clang/test/CXX/temp/temp.deduct/p9.cpp b/clang/test/CXX/temp/temp.deduct/p9.cpp index 7b661c2..5f9ea27 100644 --- a/clang/test/CXX/temp/temp.deduct/p9.cpp +++ b/clang/test/CXX/temp/temp.deduct/p9.cpp @@ -15,13 +15,14 @@ void test_f() { } template <class T, unsigned = sizeof([]() { T::invalid; })> +// expected-note@-1 {{template parameter is declared here}} void g(T); void g(...); void test_g() { - g(0); // expected-error@-4 {{type 'int' cannot be used prior to '::'}} + g(0); // expected-error@-5 {{type 'int' cannot be used prior to '::'}} // expected-note@-4 {{in instantiation of default argument}} // expected-note@-2 {{while substituting deduced template arguments}} - // expected-note@-7 {{while substituting into a lambda expression here}} + // expected-note@-8 {{while substituting into a lambda expression here}} } template <class T> diff --git a/clang/test/CXX/temp/temp.param/p1.cpp b/clang/test/CXX/temp/temp.param/p1.cpp index e9a9789..e2eecdf 100644 --- a/clang/test/CXX/temp/temp.param/p1.cpp +++ b/clang/test/CXX/temp/temp.param/p1.cpp @@ -5,8 +5,9 @@ template<template<> class C> class D; // expected-error{{template template param struct A {}; -template<class M, - class T = A, // expected-note{{previous default template argument defined here}} +template<class M, + class T // expected-note {{template parameter is declared here}} + = A, // expected-note{{previous default template argument defined here}} class C> // expected-error{{template parameter missing a default argument}} -class X0 {}; // expected-note{{template is declared here}} -X0<int> x0; // expected-error{{too few template arguments for class template 'X0'}} +class X0 {}; +X0<int> x0; // expected-error{{missing template argument for template parameter}} diff --git a/clang/test/CXX/temp/temp.param/p12.cpp b/clang/test/CXX/temp/temp.param/p12.cpp index 8317e7f..e3dfb65 100644 --- a/clang/test/CXX/temp/temp.param/p12.cpp +++ b/clang/test/CXX/temp/temp.param/p12.cpp @@ -32,9 +32,9 @@ template<int N, class B3n; // Check validity of default arguments -template<template<class, int> class =// expected-note {{previous template template parameter is here}} +template<template<class, int> class =// expected-note {{template parameter is declared here}} Y1> // expected-error{{too many template arguments for class template 'Y1'}} - // expected-note@-1 {{template template argument has different template parameters than its corresponding template template parameter}} + // expected-note@-1 {{template template argument is incompatible}} class C1 {}; C1<> c1; // expected-note{{while checking a default template argument}} diff --git a/clang/test/CXX/temp/temp.param/p15-cxx0x.cpp b/clang/test/CXX/temp/temp.param/p15-cxx0x.cpp index 238490c..ce29766 100644 --- a/clang/test/CXX/temp/temp.param/p15-cxx0x.cpp +++ b/clang/test/CXX/temp/temp.param/p15-cxx0x.cpp @@ -77,9 +77,9 @@ template<typename T> struct wrap { template<typename T> struct takedrop_impl; template<place...X> struct takedrop_impl<places<X...>> { - template<template<decltype(X)> class ...Take, + template<template<decltype(X)> class ...Take, // expected-note 2{{template parameter is declared here}} template<place > class ...Drop> - struct inner { // expected-note 2{{declared}} + struct inner { typedef types<typename Take<_>::type...> take; typedef types<typename Drop<_>::type...> drop; }; @@ -87,11 +87,11 @@ template<place...X> struct takedrop_impl<places<X...>> { template<unsigned N, typename...Ts> struct take { using type = typename takedrop_impl<typename make_places<N>::type>:: - template inner<wrap<Ts>::template inner...>::take; // expected-error {{too few template arguments}} + template inner<wrap<Ts>::template inner...>::take; // expected-error {{missing template argument}} }; template<unsigned N, typename...Ts> struct drop { using type = typename takedrop_impl<typename make_places<N>::type>:: - template inner<wrap<Ts>::template inner...>::drop; // expected-error {{too few template arguments}} + template inner<wrap<Ts>::template inner...>::drop; // expected-error {{missing template argument}} }; using T1 = take<3, int, char, double, long>::type; // expected-note {{previous}} @@ -118,7 +118,7 @@ using D3 = drop<5, int, char, double, long>::type; // expected-note {{in instant // implicitly a pack expansion. template<typename ...Default> struct DefArg { template<template<typename T = Default> class ...Classes> struct Inner { // expected-error {{default argument contains unexpanded parameter pack}} expected-note {{here}} - Inner(Classes<>...); // expected-error {{too few}} + Inner(Classes<>...); // expected-error {{missing template argument}} }; }; template<typename T> struct vector {}; diff --git a/clang/test/CXX/temp/temp.param/p8-cxx20.cpp b/clang/test/CXX/temp/temp.param/p8-cxx20.cpp index a3478c0..aa1666f 100644 --- a/clang/test/CXX/temp/temp.param/p8-cxx20.cpp +++ b/clang/test/CXX/temp/temp.param/p8-cxx20.cpp @@ -59,7 +59,7 @@ namespace ConstDestruction { f<D{1, true}>(); } - template<D d> struct Z {}; + template<D d> struct Z {}; // expected-note {{template parameter is declared here}} Z<D{2, true}> z1; Z<D{2, false}> z2; // expected-error {{non-type template argument is not a constant expression}} expected-note-re {{in call to '{{.*}}.~D()'}} } diff --git a/clang/test/CXX/temp/temp.res/temp.dep/temp.dep.constexpr/p2.cpp b/clang/test/CXX/temp/temp.res/temp.dep/temp.dep.constexpr/p2.cpp index ecb8237..cb048ec 100644 --- a/clang/test/CXX/temp/temp.res/temp.dep/temp.dep.constexpr/p2.cpp +++ b/clang/test/CXX/temp/temp.res/temp.dep/temp.dep.constexpr/p2.cpp @@ -2,7 +2,7 @@ // RUN: %clang_cc1 -std=c++11 -verify=cxx11 %s // cxx11-no-diagnostics -template<int n> struct S; +template<int n> struct S; // cxx98-note {{template parameter is declared here}} template<int n> struct T { T() { diff --git a/clang/test/CXX/temp/temp.spec/cxx1y-variable-template-no-body.cpp b/clang/test/CXX/temp/temp.spec/cxx1y-variable-template-no-body.cpp index 741ebc5..749b455 100644 --- a/clang/test/CXX/temp/temp.spec/cxx1y-variable-template-no-body.cpp +++ b/clang/test/CXX/temp/temp.spec/cxx1y-variable-template-no-body.cpp @@ -3,27 +3,27 @@ // RUN: not %clang_cc1 --std=c++1y -x c++ -fixit %t -DFIXING // RUN: %clang_cc1 --std=c++1y -x c++ %t -DFIXING -template<typename T> -T pi = T(3.1415926535897932385); // expected-note {{template is declared here}} +template<typename T> // expected-note {{template parameter is declared here}} +T pi = T(3.1415926535897932385); template int pi<int>; #ifndef FIXING -template float pi<>; // expected-error {{too few template arguments for variable template 'pi'}} +template float pi<>; // expected-error {{missing template argument for template parameter}} template double pi_var0; // expected-error {{explicit instantiation of 'pi_var0' does not refer to a function template, variable template, member function, member class, or static data member}} #endif // Should recover as if definition template double pi_var = 5; // expected-error {{variable cannot be defined in an explicit instantiation; if this declaration is meant to be a variable definition, remove the 'template' keyword}} #ifndef FIXING -template<typename T> +template<typename T> T pi0 = T(3.1415926535897932385); // expected-note {{previous definition is here}} template int pi0 = 10; // expected-error {{variable cannot be defined in an explicit instantiation; if this declaration is meant to be a variable definition, remove the 'template' keyword}} \ expected-error{{redefinition of 'pi0' as different kind of symbol}} #endif -template<typename T> +template<typename T> T pi1 = T(3.1415926535897932385); // expected-note 0-2 {{here}} // Should recover as if specialization diff --git a/clang/test/CXX/temp/temp.spec/part.spec.cpp b/clang/test/CXX/temp/temp.spec/part.spec.cpp index 4b0fdb9..3923d16 100644 --- a/clang/test/CXX/temp/temp.spec/part.spec.cpp +++ b/clang/test/CXX/temp/temp.spec/part.spec.cpp @@ -250,7 +250,7 @@ template <typename T> class PCT1 {}; template <typename T1, typename T2> class PCT2 {}; template <int X> class PCT3 {}; template <void (TestClass::*)()> class PCT4 {}; -template <void (*)()> class PCT5 {}; +template <void (*)()> class PCT5 {}; // expected-note {{template parameter is declared here}} template <typename T> class PCT6 { // expected-note@+1 3{{implicitly declared private here}} template <typename NT> class NPCT1 {}; @@ -416,7 +416,7 @@ template <typename T1, typename T2> class PCTT1 {}; template <typename T1, typename T2, typename T3> class PCTT2 {}; template <typename T, int X> class PCTT3 {}; template <typename T, void (TestClass::*)()> class PCTT4 {}; -template <typename T, void (*)()> class PCTT5 {}; +template <typename T, void (*)()> class PCTT5 {}; // expected-note {{template parameter is declared here}} template <typename T1, typename T2> class PCTT6 { template <typename NT> class NCT1 {}; template <typename NT> class NCT2; // forward declaration diff --git a/clang/test/CXX/temp/temp.spec/temp.expl.spec/p20.cpp b/clang/test/CXX/temp/temp.spec/temp.expl.spec/p20.cpp index 0283dba..63fd997 100644 --- a/clang/test/CXX/temp/temp.spec/temp.expl.spec/p20.cpp +++ b/clang/test/CXX/temp/temp.spec/temp.expl.spec/p20.cpp @@ -2,13 +2,13 @@ template<typename T> void f(T); -template<typename T> -struct A { }; // expected-note{{template is declared here}} +template<typename T> // expected-note {{template parameter is declared here}} +struct A { }; struct X { template<> friend void f<int>(int); // expected-error{{in a friend}} template<> friend class A<int>; // expected-error{{cannot be a friend}} - + friend void f<float>(float); // okay friend class A<float>; // okay }; @@ -18,6 +18,6 @@ struct PR41792 { template <> friend void f<>(int); // expected-error@+2{{template specialization declaration cannot be a friend}} - // expected-error@+1{{too few template arguments for class template 'A'}} + // expected-error@+1{{missing template argument for template parameter}} template <> friend class A<>; }; diff --git a/clang/test/Misc/integer-literal-printing.cpp b/clang/test/Misc/integer-literal-printing.cpp index bd231a3..bc52b3f0 100644 --- a/clang/test/Misc/integer-literal-printing.cpp +++ b/clang/test/Misc/integer-literal-printing.cpp @@ -14,6 +14,7 @@ enum class boolTy : bool { template <boolTy T> struct Type3Helper; template <> struct Type3Helper<boolTy::b> { typedef boolTy Ty; }; template <boolTy T, typename Type3Helper<T>::Ty U> struct Type3 {}; +// expected-note@-1 {{template parameter is declared here}} // PR14386 enum class charTy : char { @@ -23,6 +24,7 @@ enum class charTy : char { template <charTy T> struct Type4Helper; template <> struct Type4Helper<charTy::c> { typedef charTy Ty; }; template <charTy T, typename Type4Helper<T>::Ty U> struct Type4 {}; +// expected-note@-1 {{template parameter is declared here}} enum class scharTy : signed char { c = 0, @@ -31,6 +33,7 @@ enum class scharTy : signed char { template <scharTy T> struct Type5Helper; template <> struct Type5Helper<scharTy::c> { typedef scharTy Ty; }; template <scharTy T, typename Type5Helper<T>::Ty U> struct Type5 {}; +// expected-note@-1 {{template parameter is declared here}} enum class ucharTy : unsigned char { c = 0, @@ -39,6 +42,7 @@ enum class ucharTy : unsigned char { template <ucharTy T> struct Type6Helper; template <> struct Type6Helper<ucharTy::c> { typedef ucharTy Ty; }; template <ucharTy T, typename Type6Helper<T>::Ty U> struct Type6 {}; +// expected-note@-1 {{template parameter is declared here}} enum class wcharTy : wchar_t { c = 0, @@ -47,6 +51,7 @@ enum class wcharTy : wchar_t { template <wcharTy T> struct Type7Helper; template <> struct Type7Helper<wcharTy::c> { typedef wcharTy Ty; }; template <wcharTy T, typename Type7Helper<T>::Ty U> struct Type7 {}; +// expected-note@-1 {{template parameter is declared here}} enum class char16Ty : char16_t { c = 0, @@ -55,6 +60,7 @@ enum class char16Ty : char16_t { template <char16Ty T> struct Type8Helper; template <> struct Type8Helper<char16Ty::c> { typedef char16Ty Ty; }; template <char16Ty T, typename Type8Helper<T>::Ty U> struct Type8 {}; +// expected-note@-1 {{template parameter is declared here}} enum class char32Ty : char16_t { c = 0, @@ -63,6 +69,7 @@ enum class char32Ty : char16_t { template <char32Ty T> struct Type9Helper; template <> struct Type9Helper<char32Ty::c> { typedef char32Ty Ty; }; template <char32Ty T, typename Type9Helper<T>::Ty U> struct Type9 {}; +// expected-note@-1 {{template parameter is declared here}} void Function() { Function1(Type1<-42>()); // expected-error{{no matching function for call to 'Function1'}} diff --git a/clang/test/Modules/malformed-constraint-template-non-type-parm-decl.cpp b/clang/test/Modules/malformed-constraint-template-non-type-parm-decl.cpp index 73dff88..250b54a 100644 --- a/clang/test/Modules/malformed-constraint-template-non-type-parm-decl.cpp +++ b/clang/test/Modules/malformed-constraint-template-non-type-parm-decl.cpp @@ -11,7 +11,7 @@ //--- mod.cppm export module mod; -template <typename T, auto Q> +template <typename T, auto Q> // expected-note 2{{template parameter is declared here}} concept ReferenceOf = Q; // expected-error@+2 {{unknown type name 'AngleIsInvalidNow'}} diff --git a/clang/test/Modules/missing-body-in-import.cpp b/clang/test/Modules/missing-body-in-import.cpp index b52ebba..e25f7b5 100644 --- a/clang/test/Modules/missing-body-in-import.cpp +++ b/clang/test/Modules/missing-body-in-import.cpp @@ -29,6 +29,7 @@ export module mod2; import mod1; struct C: B <A{"a", "b"}> { // expected-error {{non-type template argument is not a constant expression}} + // expected-note@mod1.cppm:11 {{template parameter is declared here}} constexpr C(int a) { } }; diff --git a/clang/test/Modules/template-default-args.cpp b/clang/test/Modules/template-default-args.cpp index 85b2a18..1d8de70 100644 --- a/clang/test/Modules/template-default-args.cpp +++ b/clang/test/Modules/template-default-args.cpp @@ -22,7 +22,7 @@ template<typename T = int> struct B; template<typename T = int> struct C; template<typename T> struct D {}; template<typename T> struct F {}; -template<typename T> struct G {}; +template<typename T> struct G {}; // #G template<typename T> struct J {}; template<typename T = int> struct J; struct K : J<> {}; @@ -39,8 +39,10 @@ E<> e; F<> f; G<> g; // expected-error {{missing '#include "a.h"'; default argument of 'G' must be defined before it is used}} // expected-note@a.h:7 {{default argument declared here is not reachable}} +// expected-note@#G {{template parameter is declared here}} H<> h; // expected-error {{missing '#include "a.h"'; default argument of 'H' must be defined before it is used}} // expected-note@a.h:8 {{default argument declared here is not reachable}} +// expected-note@a.h:8 {{template parameter is declared here}} I<> i; L<> *l; END diff --git a/clang/test/Parser/MicrosoftExtensions.cpp b/clang/test/Parser/MicrosoftExtensions.cpp index e32d7fa..9989fb8 100644 --- a/clang/test/Parser/MicrosoftExtensions.cpp +++ b/clang/test/Parser/MicrosoftExtensions.cpp @@ -126,7 +126,7 @@ void template_uuid() } -template <class T, const GUID* g = &__uuidof(T)> // expected-note {{template parameter is declared here}} +template <class T, const GUID* g = &__uuidof(T)> // expected-note 2{{template parameter is declared here}} class COM_CLASS_TEMPLATE { }; typedef COM_CLASS_TEMPLATE<struct_with_uuid, &*&__uuidof(struct_with_uuid)> COM_TYPE_1; // expected-warning {{non-type template argument containing a dereference operation is a Microsoft extension}} diff --git a/clang/test/Parser/cxx-template-argument.cpp b/clang/test/Parser/cxx-template-argument.cpp index 3c2169f..ffe53e7 100644 --- a/clang/test/Parser/cxx-template-argument.cpp +++ b/clang/test/Parser/cxx-template-argument.cpp @@ -57,9 +57,9 @@ namespace PR13210 { // Don't emit spurious messages namespace pr16225add { - template<class T1, typename T2> struct Known { }; // expected-note 3 {{template is declared here}} + template<class T1, typename T2> struct Known { }; // expected-note 3{{template parameter is declared here}} template<class T1, typename T2> struct X; - template<class T1, typename T2> struct ABC; // expected-note {{template is declared here}} + template<class T1, typename T2> struct ABC; // expected-note {{template parameter is declared here}} template<int N1, int N2> struct ABC2 {}; template<class T1, typename T2> struct foo : @@ -68,7 +68,7 @@ namespace pr16225add { template<class T1, typename T2> struct foo2 : UnknownBase<T1,T2>, // expected-error {{no template named 'UnknownBase'}} - Known<T1> // expected-error {{too few template arguments for class template 'Known'}} + Known<T1> // expected-error {{missing template argument for template parameter}} { }; template<class T1, typename T2> struct foo3 : @@ -76,8 +76,8 @@ namespace pr16225add { { }; template<class T1, typename T2> struct foo4 : - UnknownBase<T1,ABC<T2> >, // expected-error {{too few template arguments for class template 'ABC'}} - Known<T1> // expected-error {{too few template arguments for class template 'Known'}} + UnknownBase<T1,ABC<T2> >, // expected-error {{missing template argument for template parameter}} + Known<T1> // expected-error {{missing template argument for template parameter}} { }; template<class T1, typename T2> struct foo5 : @@ -92,7 +92,7 @@ namespace pr16225add { #if __cplusplus <= 199711L // expected-error@-2 {{use '> >'}} #endif - Known<T1> // expected-error {{too few template arguments for class template 'Known'}} + Known<T1> // expected-error {{missing template argument for template parameter}} { }; template<class T1, typename T2, int N> struct foo7 : diff --git a/clang/test/Parser/cxx-template-template-recovery.cpp b/clang/test/Parser/cxx-template-template-recovery.cpp index 61ef82d..5f9bf17 100644 --- a/clang/test/Parser/cxx-template-template-recovery.cpp +++ b/clang/test/Parser/cxx-template-template-recovery.cpp @@ -19,8 +19,10 @@ template <typename T> concept C3 = true; // #C3 template <typename T> auto V3 = true; // #V3 -template <template <typename T> typename C> -constexpr bool test = true; + +template <template <typename T> + typename C> // expected-note 6{{template parameter is declared here}} + constexpr bool test = true; static_assert(test<a::C1>); // expected-error {{template argument does not refer to a class or alias template, or template template parameter}} \ // expected-note@#C1 {{here}} diff --git a/clang/test/Parser/cxx1z-class-template-argument-deduction.cpp b/clang/test/Parser/cxx1z-class-template-argument-deduction.cpp index 9d27f83..a8a9f33 100644 --- a/clang/test/Parser/cxx1z-class-template-argument-deduction.cpp +++ b/clang/test/Parser/cxx1z-class-template-argument-deduction.cpp @@ -11,7 +11,7 @@ A(int) -> A<int>; // Make sure we still correctly parse cases where a template can appear without arguments. namespace template_template_arg { template<template<typename> typename> struct X {}; - template<typename> struct Y {}; + template<typename> struct Y {}; // expected-note 2{{template parameter is declared here}} X<A> xa; Y<A> ya; // expected-error {{requires template arguments}} @@ -36,7 +36,7 @@ namespace template_template_arg { namespace template_template_arg_pack { template<template<typename> typename...> struct XP {}; - template<typename...> struct YP {}; + template<typename...> struct YP {}; // expected-note 2{{template parameter is declared here}} struct Z { template<typename T> struct Q {}; }; // expected-note 2{{here}} @@ -116,7 +116,7 @@ namespace stmt { } namespace expr { - template<typename T> struct U {}; + template<typename T> struct U {}; // expected-note {{template parameter is declared here}} void j() { (void)typeid(A); // expected-error{{requires template arguments; argument deduction not allowed here}} (void)sizeof(A); // expected-error{{requires template arguments; argument deduction not allowed here}} diff --git a/clang/test/Sema/invalid-member.cpp b/clang/test/Sema/invalid-member.cpp index 0e3fec1..ccce392 100644 --- a/clang/test/Sema/invalid-member.cpp +++ b/clang/test/Sema/invalid-member.cpp @@ -22,7 +22,7 @@ static_assert(sizeof(Z) == 1, "No valid members"); constexpr int N = undef; // expected-error {{use of undeclared identifier}} \ expected-note {{declared here}} -template<int a> +template<int a> // expected-note {{template parameter is declared here}} class ABC {}; class T { ABC<N> abc; // expected-error {{non-type template argument is not a constant expression}} \ diff --git a/clang/test/SemaCXX/access-base-class.cpp b/clang/test/SemaCXX/access-base-class.cpp index 47d0f02..7d5fe38 100644 --- a/clang/test/SemaCXX/access-base-class.cpp +++ b/clang/test/SemaCXX/access-base-class.cpp @@ -1,6 +1,6 @@ // RUN: %clang_cc1 -fsyntax-only -verify %s namespace T1 { - + class A { }; class B : private A { }; // expected-note {{declared private here}} @@ -10,7 +10,7 @@ void f(B* b) { } -namespace T2 { +namespace T2 { class A { }; class B : A { }; // expected-note {{implicitly declared private here}} @@ -24,7 +24,7 @@ void f(B* b) { namespace T3 { class A { }; -class B : public A { }; +class B : public A { }; void f(B* b) { A *a = b; @@ -50,30 +50,30 @@ void f(D *d) { namespace T5 { class A {}; - + class B : private A { void f(B *b) { A *a = b; } - }; + }; } namespace T6 { class C; - + class A {}; // expected-note{{member is declared here}} - + class B : private A { // expected-note {{declared private here}} expected-note {{constrained by private inheritance here}} void f(C* c); }; - - class C : public B { + + class C : public B { void f(C *c) { A* a = c; // expected-error {{cannot cast 'C' to its private base class 'A'}} \ // expected-error {{'A' is a private member of 'T6::A'}} } }; - + void B::f(C *c) { A *a = c; } @@ -82,7 +82,7 @@ namespace T6 { namespace T7 { class A {}; class B : public A {}; - class C : private B { + class C : private B { void f(C *c) { A* a = c; // okay } @@ -98,7 +98,7 @@ struct flag { template <class T> struct trait : flag<sizeof(T)> {}; // expected-note 2{{here}} -template <class T, bool Inferred = trait<T>::value> // expected-note {{here}} +template <class T, bool Inferred = trait<T>::value> // expected-note 2{{here}} struct a {}; template <class T> diff --git a/clang/test/SemaCXX/alias-template.cpp b/clang/test/SemaCXX/alias-template.cpp index b49d36a..90095b3 100644 --- a/clang/test/SemaCXX/alias-template.cpp +++ b/clang/test/SemaCXX/alias-template.cpp @@ -167,7 +167,10 @@ namespace SFINAE { f<E>(); } - template<typename T, typename U = EnableIf<is_enum<T>>> struct fail1 {}; // expected-note {{here}} + template<typename T, + typename U = // expected-note {{template parameter is declared here}} + EnableIf<is_enum<T>>> // expected-note {{in instantiation of template type alias 'EnableIf' requested here}} + struct fail1 {}; template<typename T> struct fail2 : DisableIf<is_enum<T>> {}; // expected-note {{here}} fail1<int> f1; // expected-note {{here}} diff --git a/clang/test/SemaCXX/anonymous-struct.cpp b/clang/test/SemaCXX/anonymous-struct.cpp index 5927f4e..a8688af 100644 --- a/clang/test/SemaCXX/anonymous-struct.cpp +++ b/clang/test/SemaCXX/anonymous-struct.cpp @@ -27,7 +27,7 @@ struct E { }; }; -template <class T> void foo(T); +template <class T> void foo(T); // #foo 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}} // expected-note@-1 {{unnamed type used in template argument was declared here}} @@ -36,6 +36,7 @@ typedef struct { // expected-error {{anonymous non-C-compatible type given name #if __cplusplus <= 199711L // expected-warning@-2 {{template argument uses unnamed type}} // expected-note@-3 {{while substituting deduced template arguments}} + // expected-note@#foo {{template parameter is declared here}} #endif } } A; // expected-note {{type is given name 'A' for linkage purposes by this typedef declaration}} diff --git a/clang/test/SemaCXX/builtin-structured-binding-size.cpp b/clang/test/SemaCXX/builtin-structured-binding-size.cpp index bcd13a6..b780752 100644 --- a/clang/test/SemaCXX/builtin-structured-binding-size.cpp +++ b/clang/test/SemaCXX/builtin-structured-binding-size.cpp @@ -119,6 +119,7 @@ T<int> t1; // expected-error@#tpl-1 {{non-type template argument is not a constant expression}} \ // expected-note@-1 {{in instantiation of default argument for 'T<int>' required here}} \ // expected-note@-1 {{while checking a default template argument used here}} \ +// expected-note@#tpl-1 2{{template parameter is declared here}} static_assert(T<S3>::value == 3); diff --git a/clang/test/SemaCXX/constant-expression-cxx11.cpp b/clang/test/SemaCXX/constant-expression-cxx11.cpp index 91c4ff1..4e17121 100644 --- a/clang/test/SemaCXX/constant-expression-cxx11.cpp +++ b/clang/test/SemaCXX/constant-expression-cxx11.cpp @@ -102,7 +102,7 @@ static_assert(n9 == 123, ""); } namespace TemplateArgumentConversion { - template<int n> struct IntParam {}; + template<int n> struct IntParam {}; // expected-note {{template parameter is declared here}} using IntParam0 = IntParam<0>; using IntParam0 = IntParam<id(0)>; @@ -1533,7 +1533,7 @@ namespace MutableMembers { constexpr int mmn2 = mm.n; // expected-error {{constant expression}} expected-note {{read of mutable member 'n' is not allowed in a constant expression}} // Here's one reason why allowing this would be a disaster... - template<int n> struct Id { int k = n; }; + template<int n> struct Id { int k = n; }; // expected-note {{template parameter is declared here}} int f() { constexpr MM m = { 0 }; ++m.n; diff --git a/clang/test/SemaCXX/constant-expression.cpp b/clang/test/SemaCXX/constant-expression.cpp index ef48ee5..a710def 100644 --- a/clang/test/SemaCXX/constant-expression.cpp +++ b/clang/test/SemaCXX/constant-expression.cpp @@ -99,7 +99,7 @@ void diags(int n) { namespace IntOrEnum { const int k = 0; const int &p = k; // expected-note {{declared here}} - template<int n> struct S {}; + template<int n> struct S {}; // expected-note {{template parameter is declared here}} S<p> s; // expected-error {{not an integral constant expression}} expected-note {{read of variable 'p' of non-integral, non-enumeration type 'const int &'}} } diff --git a/clang/test/SemaCXX/cxx1z-noexcept-function-type.cpp b/clang/test/SemaCXX/cxx1z-noexcept-function-type.cpp index c8204c2..6b8495e 100644 --- a/clang/test/SemaCXX/cxx1z-noexcept-function-type.cpp +++ b/clang/test/SemaCXX/cxx1z-noexcept-function-type.cpp @@ -74,6 +74,7 @@ namespace DependentDefaultCtorExceptionSpec { }; struct InstantiateFromAnotherClass { template <class B, class T = decltype(static_cast<bool (B::*)(int)>(&B::foo))> // expected-note {{in instantiation of function template specialization}} + // expected-note@-1 {{template parameter is declared here}} InstantiateFromAnotherClass(B *) {} // expected-note {{in instantiation of default argument}} }; NoexceptWithThis<int> f{}; diff --git a/clang/test/SemaCXX/cxx2a-consteval.cpp b/clang/test/SemaCXX/cxx2a-consteval.cpp index 1474c48..54390e3f 100644 --- a/clang/test/SemaCXX/cxx2a-consteval.cpp +++ b/clang/test/SemaCXX/cxx2a-consteval.cpp @@ -201,7 +201,7 @@ struct A { using mem_ptr_type = int (A::*)(int); -template<mem_ptr_type ptr> +template<mem_ptr_type ptr> // expected-note 2{{template parameter is declared here}} struct C {}; C<&A::f> c; diff --git a/clang/test/SemaCXX/cxx2c-template-template-param.cpp b/clang/test/SemaCXX/cxx2c-template-template-param.cpp index ed55a059..a0b8d79 100644 --- a/clang/test/SemaCXX/cxx2c-template-template-param.cpp +++ b/clang/test/SemaCXX/cxx2c-template-template-param.cpp @@ -3,12 +3,16 @@ namespace Errors { template <template<typename T> auto> +// expected-note@-1 4{{template parameter is declared here}} struct S1; template <template<auto T> auto> +// expected-note@-1 4{{template parameter is declared here}} struct S2; template <template<typename T> concept> +// expected-note@-1 4{{template parameter is declared here}} struct S3; template <template<auto T> concept> +// expected-note@-1 4{{template parameter is declared here}} struct S4; int a; @@ -36,7 +40,7 @@ S4<Var> t16; // expected-error {{template argument does not refer to a concept, } -template <template<typename T> auto V> // expected-note {{previous template template parameter is here}} \ +template <template<typename T> auto V> // expected-note {{template parameter is declared here}} \ // expected-error{{template argument for non-type template parameter must be an expression}} struct S1 { static_assert(V<int> == 42); @@ -44,18 +48,18 @@ struct S1 { static_assert(V<double> == 0); }; template <template<auto T> auto V> // expected-error {{template argument for template type parameter must be a type}} \ - // expected-note {{previous template template parameter is here}} + // expected-note {{template parameter is declared here}} struct S2 { static_assert(V<0> == 1); static_assert(V<1> == 0); }; template <template<typename T> concept C > // expected-error {{template argument for non-type template parameter must be an expression}} \ - // expected-note {{previous template template parameter is here}} + // expected-note {{template parameter is declared here}} struct S3 { static_assert(C<int>); }; template <template<auto> concept C> // expected-error {{template argument for template type parameter must be a type}} \ - // expected-note {{previous template template parameter is here}} + // expected-note {{template parameter is declared here}} struct S4 { static_assert(C<0>); }; @@ -80,14 +84,14 @@ requires (N%2 == 0) constexpr auto Var2<N> = 1; void test () { - S1<Var2> sE; // expected-note {{template template argument has different template parameters than its corresponding template template parameter}} - S2<Var> sE; // expected-note {{template template argument has different template parameters than its corresponding template template parameter}} + S1<Var2> sE; // expected-note {{template template argument is incompatible with its corresponding template template parameter}} + S2<Var> sE; // expected-note {{template template argument is incompatible with its corresponding template template parameter}} S1<Var> s1; S2<Var2> s2; S3<C> s3; - S4<C> sE; // expected-note {{template template argument has different template parameters than its corresponding template template parameter}} + S4<C> sE; // expected-note {{template template argument is incompatible with its corresponding template template parameter}} S4<CI> s4; - S3<CI> sE; // expected-note {{template template argument has different template parameters than its corresponding template template parameter}} + S3<CI> sE; // expected-note {{template template argument is incompatible with its corresponding template template parameter}} } @@ -342,10 +346,11 @@ concept D = Var<int>; namespace InvalidName { template <typename T, template <typename> concept C> -concept A = C<T>; // expected-note {{here}} +// expected-note@-1 {{template parameter is declared here}} +concept A = C<T>; template <A<concept missing<int>> T> // expected-error {{expected expression}} \ - // expected-error {{too few template arguments for concept 'A'}} \ + // expected-error {{missing template argument for template parameter}} \ // expected-error {{unknown type name 'T'}} \ // expected-error {{expected unqualified-id}} auto f(); diff --git a/clang/test/SemaCXX/cxx98-compat-flags.cpp b/clang/test/SemaCXX/cxx98-compat-flags.cpp index 6ffb3a5..3986251 100644 --- a/clang/test/SemaCXX/cxx98-compat-flags.cpp +++ b/clang/test/SemaCXX/cxx98-compat-flags.cpp @@ -1,7 +1,8 @@ // RUN: %clang_cc1 -fsyntax-only -std=c++17 -Wc++98-compat-pedantic -verify %s // RUN: %clang_cc1 -fsyntax-only -std=c++17 -Wc++98-compat-pedantic -Wno-bind-to-temporary-copy -Wno-unnamed-type-template-args -Wno-local-type-template-args -Wno-binary-literal -Werror %s -template<typename T> int TemplateFn(T) { return 0; } +template<typename T> // expected-note 2{{template parameter is declared here}} +int TemplateFn(T) { return 0; } void LocalTemplateArg() { struct S {}; TemplateFn(S()); // expected-warning {{local type 'S' as template argument is incompatible with C++98}} diff --git a/clang/test/SemaCXX/cxx98-compat.cpp b/clang/test/SemaCXX/cxx98-compat.cpp index 8e7acf7..9a8a8e2 100644 --- a/clang/test/SemaCXX/cxx98-compat.cpp +++ b/clang/test/SemaCXX/cxx98-compat.cpp @@ -183,7 +183,8 @@ struct DelegCtor { template<int n = 0> void DefaultFuncTemplateArg(); // expected-warning {{default template arguments for a function template are incompatible with C++98}} -template<typename T> int TemplateFn(T) { return 0; } +template<typename T> // expected-note 2{{template parameter is declared here}} +int TemplateFn(T) { return 0; } void LocalTemplateArg() { struct S {}; TemplateFn(S()); // expected-warning {{local type 'S' as template argument is incompatible with C++98}} @@ -198,7 +199,7 @@ int UnnamedTemplateArg = TemplateFn(obj_of_unnamed_type); // expected-warning {{ #ifndef CXX17COMPAT namespace RedundantParensInAddressTemplateParam { int n; - template<int*p> struct S {}; + template<int*p> struct S {}; // expected-note 2{{template parameter is declared here}} S<(&n)> s; // expected-warning {{parentheses around address non-type template argument are incompatible with C++98}} S<(((&n)))> t; // expected-warning {{parentheses around address non-type template argument are incompatible with C++98}} } @@ -321,7 +322,7 @@ namespace LiteralUCNs { // template argument evaluation rules. #ifndef CXX17COMPAT namespace NonTypeTemplateArgs { - template<typename T, T v> struct S {}; + template<typename T, T v> struct S {}; // expected-note 2{{template parameter is declared here}} const int k = 5; // expected-note {{here}} static void f() {} // expected-note {{here}} S<const int&, k> s1; // expected-warning {{non-type template argument referring to object 'k' with internal linkage is incompatible with C++98}} @@ -330,8 +331,8 @@ namespace NonTypeTemplateArgs { namespace NullPointerTemplateArg { struct A {}; - template<int*> struct X {}; - template<int A::*> struct Y {}; + template<int*> struct X {}; // expected-note {{template parameter is declared here}} + template<int A::*> struct Y {}; // expected-note {{template parameter is declared here}} X<(int*)0> x; // expected-warning {{use of null pointer as non-type template argument is incompatible with C++98}} Y<(int A::*)0> y; // expected-warning {{use of null pointer as non-type template argument is incompatible with C++98}} } diff --git a/clang/test/SemaCXX/invalid-requirement-requires-expr.cpp b/clang/test/SemaCXX/invalid-requirement-requires-expr.cpp index 097ada3..436dfb9 100644 --- a/clang/test/SemaCXX/invalid-requirement-requires-expr.cpp +++ b/clang/test/SemaCXX/invalid-requirement-requires-expr.cpp @@ -17,8 +17,7 @@ constexpr bool A<x>::far() { b.data_member; requires A<x-1>::far(); // #Invalid // expected-error@#Invalid {{recursive template instantiation exceeded maximum depth}} - // expected-note@#Invalid {{in instantiation}} - // expected-note@#Invalid 2 {{while}} + // expected-note@#Invalid 3 {{while}} // expected-note@#Invalid {{contexts in backtrace}} // expected-note@#Invalid {{increase recursive template instantiation depth}} }; diff --git a/clang/test/SemaCXX/invalid-std-initializer-list.cpp b/clang/test/SemaCXX/invalid-std-initializer-list.cpp index 93246b5..6f8af52 100644 --- a/clang/test/SemaCXX/invalid-std-initializer-list.cpp +++ b/clang/test/SemaCXX/invalid-std-initializer-list.cpp @@ -2,7 +2,9 @@ namespace std { -template<class T, class = T::x> // expected-error 2 {{type 'int' cannot be used prior to '::' because it has no members}} +template<class T, + class = // expected-note 2 {{template parameter is declared here}} + T::x> // expected-error 2 {{type 'int' cannot be used prior to '::' because it has no members}} class initializer_list; } diff --git a/clang/test/SemaCXX/lambda-expressions.cpp b/clang/test/SemaCXX/lambda-expressions.cpp index 8ea8e32..a6803ea 100644 --- a/clang/test/SemaCXX/lambda-expressions.cpp +++ b/clang/test/SemaCXX/lambda-expressions.cpp @@ -447,7 +447,7 @@ struct A { // expected-error@-1 {{field has incomplete type 'void'}} }; -template <typename F> +template <typename F> // cxx03-note {{template parameter is declared here}} void g(F f) { auto a = A<decltype(f())>(); // expected-note@-1 {{in instantiation of template class 'PR20731::A<void>' requested here}} @@ -504,12 +504,14 @@ namespace error_in_transform_prototype { namespace PR21857 { template<typename Fn> struct fun : Fn { + // cxx03-note@-1 {{template parameter is declared here}} fun() = default; using Fn::operator(); }; template<typename Fn> fun<Fn> wrap(Fn fn); // cxx03-warning {{template argument uses unnamed type}} + // cxx03-note@-1 {{template parameter is declared here}} 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}} + // cxx03-note@-1 2{{while substituting deduced template arguments into function template}} } namespace PR13987 { diff --git a/clang/test/SemaCXX/make_integer_seq.cpp b/clang/test/SemaCXX/make_integer_seq.cpp index 71b7b82..7fca9ed 100644 --- a/clang/test/SemaCXX/make_integer_seq.cpp +++ b/clang/test/SemaCXX/make_integer_seq.cpp @@ -48,5 +48,6 @@ using illformed2 = ErrorSeq<int, -5>; // expected-note{{in instantiation}} template <typename T, T N> void f() {} __make_integer_seq<f, int, 0> x; // expected-error{{template template parameter must be a class template or type alias template}} -__make_integer_seq<__make_integer_seq, int, 10> PR28494; // expected-note{{different template parameters}} +__make_integer_seq<__make_integer_seq, int, 10> PR28494; // expected-note{{template template argument is incompatible}} // expected-error@make_integer_seq.cpp:* {{template argument for template template parameter must be a class template or type alias template}} +// expected-note@*:* 3{{template parameter from hidden source: template <class, type-parameter-1-0 ...> class}} diff --git a/clang/test/SemaCXX/type-trait-common-type.cpp b/clang/test/SemaCXX/type-trait-common-type.cpp index 8f2b97b..214f946 100644 --- a/clang/test/SemaCXX/type-trait-common-type.cpp +++ b/clang/test/SemaCXX/type-trait-common-type.cpp @@ -5,10 +5,12 @@ # error #endif -// expected-note@*:* {{template declaration from hidden source: template <template <class ...> class, template <class> class, class, class ...>}} +// expected-note@*:* {{template parameter from hidden source: template <class ...> class}} +// expected-note@*:* {{template parameter from hidden source: class ...}} +// expected-note@*:* 2{{template parameter from hidden source: template <class ...> class}} void test() { - __builtin_common_type<> a; // expected-error {{too few template arguments for template '__builtin_common_type'}} + __builtin_common_type<> a; // expected-error {{missing template argument for template parameter}} __builtin_common_type<1> b; // expected-error {{template argument for template template parameter must be a class template or type alias template}} __builtin_common_type<int, 1> c; // expected-error {{template argument for template template parameter must be a class template or type alias template}} } @@ -219,6 +221,7 @@ static_assert(__is_same(common_type_base<int, PrivateConstructor>, empty_type)); // expected-note@+1 {{in instantiation of template type alias 'common_type_base' requested here}} template<typename A, typename B, typename Res = common_type_base<A, B>> +// expected-note@-1 {{template parameter is declared here}} static Res common_type_sfinae(); // expected-note@-1 {{in instantiation of default argument for 'common_type_sfinae<int, InvalidConversion>' required here}} diff --git a/clang/test/SemaCXX/undefined-internal.cpp b/clang/test/SemaCXX/undefined-internal.cpp index 9745f09..7f46623 100644 --- a/clang/test/SemaCXX/undefined-internal.cpp +++ b/clang/test/SemaCXX/undefined-internal.cpp @@ -209,9 +209,11 @@ 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-note@-4 {{while substituting explicitly-specified template arguments}} - // expected-warning@-4 {{non-type template argument referring to function 'f' with internal linkage}} + // expected-note@-7 {{template parameter is declared here}} // expected-note@-5 {{while substituting explicitly-specified template arguments}} + // expected-warning@-5 {{non-type template argument referring to function 'f' with internal linkage}} + // expected-note@-9 {{template parameter is declared here}} + // expected-note@-7 {{while substituting explicitly-specified template arguments}} #endif } } diff --git a/clang/test/SemaCXX/warn-deprecated-specializations-in-system-headers.cpp b/clang/test/SemaCXX/warn-deprecated-specializations-in-system-headers.cpp index 79c9d33..1fe0916 100644 --- a/clang/test/SemaCXX/warn-deprecated-specializations-in-system-headers.cpp +++ b/clang/test/SemaCXX/warn-deprecated-specializations-in-system-headers.cpp @@ -10,6 +10,7 @@ template <> struct [[deprecated]] traits<int> {}; // expected-note {{'traits<int>' has been explicitly marked deprecated here}} template<typename T, typename Trait = traits<T>> // expected-warning {{'traits<int>' is deprecated}} + // expected-note@-1 {{template parameter is declared here}} struct basic_string {}; // should not warn, defined and used in system headers diff --git a/clang/test/SemaHLSL/BuiltIns/Buffers.hlsl b/clang/test/SemaHLSL/BuiltIns/Buffers.hlsl index d7c6876..31fdf65 100644 --- a/clang/test/SemaHLSL/BuiltIns/Buffers.hlsl +++ b/clang/test/SemaHLSL/BuiltIns/Buffers.hlsl @@ -8,7 +8,7 @@ typedef vector<double, 3> double3; // expected-error@+1 {{class template 'Buffer' requires template arguments}} Buffer BufferErr1; -// expected-error@+1 {{too few template arguments for class template 'Buffer'}} +// expected-error@+1 {{missing template argument for template parameter}} Buffer<> BufferErr2; // test implicit Buffer concept @@ -39,7 +39,7 @@ template<typename T> struct TemplatedVector { // structs not allowed // expected-error@+4 {{constraints not satisfied for class template 'Buffer'}} -// expected-note@*:* {{template declaration from hidden source: template <typename element_type> requires __is_typed_resource_element_compatible<element_type> class Buffer}} +// expected-note@*:* {{template parameter from hidden source: typename element_type}} // expected-note@*:* {{because 's' does not satisfy '__is_typed_resource_element_compatible'}} // expected-note@*:* {{because '__builtin_hlsl_is_typed_resource_element_compatible(s)' evaluated to false}} Buffer<s> r6; diff --git a/clang/test/SemaHLSL/BuiltIns/RWBuffers.hlsl b/clang/test/SemaHLSL/BuiltIns/RWBuffers.hlsl index 361f4303..78a6d5f 100644 --- a/clang/test/SemaHLSL/BuiltIns/RWBuffers.hlsl +++ b/clang/test/SemaHLSL/BuiltIns/RWBuffers.hlsl @@ -8,7 +8,7 @@ typedef vector<double, 3> double3; // expected-error@+1 {{class template 'RWBuffer' requires template arguments}} RWBuffer BufferErr1; -// expected-error@+1 {{too few template arguments for class template 'RWBuffer'}} +// expected-error@+1 {{missing template argument for template parameter}} RWBuffer<> BufferErr2; // test implicit RWBuffer concept @@ -39,7 +39,7 @@ template<typename T> struct TemplatedVector { // structs not allowed // expected-error@+4 {{constraints not satisfied for class template 'RWBuffer'}} -// expected-note@*:* {{template declaration from hidden source: template <typename element_type> requires __is_typed_resource_element_compatible<element_type> class RWBuffer}} +// expected-note@*:* {{template parameter from hidden source: typename element_type}} // expected-note@*:* {{because 's' does not satisfy '__is_typed_resource_element_compatible'}} // expected-note@*:* {{because '__builtin_hlsl_is_typed_resource_element_compatible(s)' evaluated to false}} RWBuffer<s> r6; diff --git a/clang/test/SemaHLSL/BuiltIns/StructuredBuffers.hlsl b/clang/test/SemaHLSL/BuiltIns/StructuredBuffers.hlsl index e5b1125..6bb71dd 100644 --- a/clang/test/SemaHLSL/BuiltIns/StructuredBuffers.hlsl +++ b/clang/test/SemaHLSL/BuiltIns/StructuredBuffers.hlsl @@ -8,8 +8,8 @@ StructuredBuffer<float3> Buff; // expected-note@*:* {{template declaration from hidden source: template <typename element_type> requires __is_structured_resource_element_compatible<element_type> class StructuredBuffer {}}} StructuredBuffer BufferErr1; -// expected-error@+2 {{too few template arguments for class template 'StructuredBuffer'}} -// expected-note@*:* {{template declaration from hidden source: template <typename element_type> requires __is_structured_resource_element_compatible<element_type> class StructuredBuffer {}}} +// expected-error@+2 {{missing template argument for template parameter}} +// expected-note@*:* {{template parameter from hidden source: typename element_type}} StructuredBuffer<> BufferErr2; // test elements of 0 size diff --git a/clang/test/SemaObjCXX/parameterized_classes_subst.mm b/clang/test/SemaObjCXX/parameterized_classes_subst.mm index 4658c3d..728e9d4 100644 --- a/clang/test/SemaObjCXX/parameterized_classes_subst.mm +++ b/clang/test/SemaObjCXX/parameterized_classes_subst.mm @@ -408,7 +408,7 @@ void testVariadicInstantiation() { // -------------------------------------------------------------------------- // Parameterized classes are not templates // -------------------------------------------------------------------------- -template<template<typename T, typename U> class TT> +template<template<typename T, typename U> class TT> // expected-note {{template parameter is declared here}} struct AcceptsTemplateTemplate { }; typedef AcceptsTemplateTemplate<NSMutableDictionary> TemplateTemplateFail1; // expected-error{{template argument for template template parameter must be a class template or type alias template}} diff --git a/clang/test/SemaTemplate/alias-templates.cpp b/clang/test/SemaTemplate/alias-templates.cpp index ab5cad7..7ec420a 100644 --- a/clang/test/SemaTemplate/alias-templates.cpp +++ b/clang/test/SemaTemplate/alias-templates.cpp @@ -278,12 +278,12 @@ namespace PR31514 { namespace an_alias_template_is_not_a_class_template { template<typename T> using Foo = int; // expected-note 3{{here}} Foo x; // expected-error {{use of alias template 'Foo' requires template arguments}} - Foo<> y; // expected-error {{too few template arguments for alias template 'Foo'}} + Foo<> y; // expected-error {{missing template argument for template parameter}} int z = Foo(); // expected-error {{use of alias template 'Foo' requires template arguments}} template<template<typename> class Bar> void f() { // expected-note 3{{here}} Bar x; // expected-error {{use of template template parameter 'Bar' requires template arguments}} - Bar<> y; // expected-error {{too few template arguments for template template parameter 'Bar'}} + Bar<> y; // expected-error {{missing template argument for template parameter}} int z = Bar(); // expected-error {{use of template template parameter 'Bar' requires template arguments}} } } @@ -304,7 +304,8 @@ namespace resolved_nttp { using TB = int (*)(int (*)[1], int (*)[2], int (*)[3]); template <typename T, int ...M> struct C { - template <T... N> using Fn = T(int(*...A)[N]); + template <T... N> // expected-note {{template parameter is declared here}} + using Fn = T(int(*...A)[N]); Fn<1, M..., 4> *p; // expected-error-re 3{{evaluates to {{[234]}}, which cannot be narrowed to type 'bool'}} }; using TC = decltype(C<int, 2, 3>::p); diff --git a/clang/test/SemaTemplate/concepts.cpp b/clang/test/SemaTemplate/concepts.cpp index 209e7dc..505562a 100644 --- a/clang/test/SemaTemplate/concepts.cpp +++ b/clang/test/SemaTemplate/concepts.cpp @@ -1262,7 +1262,8 @@ constexpr bool f(C auto) { // #GH61824_f C auto x = 0; // expected-error@#T_Type {{type 'int' cannot be used prior to '::'}} \ -// expected-note@-1 {{in instantiation of default argument}} +// expected-note@-1 {{in instantiation of default argument}} \ +// expected-note@#T_Type {{template parameter is declared here}} // This will be fixed when we merge https://github.com/llvm/llvm-project/pull/141776 // Which makes us behave like GCC. diff --git a/clang/test/SemaTemplate/cwg2398.cpp b/clang/test/SemaTemplate/cwg2398.cpp index 315fa95..81079df 100644 --- a/clang/test/SemaTemplate/cwg2398.cpp +++ b/clang/test/SemaTemplate/cwg2398.cpp @@ -264,7 +264,7 @@ namespace classes { template<class T, class U> struct A {}; template<template<class> class TT> auto f(TT<int> a) { return a; } - // expected-note@-1 2{{substitution failure: too few template arguments}} + // expected-note@-1 2{{no template parameter}} A<int, float> v1; A<int, double> v2; @@ -280,7 +280,7 @@ namespace classes { static constexpr auto val = E1; }; template <template <class T3> class TT> void f(TT<int> v) { - // expected-note@-1 {{substitution failure: too few template arguments}} + // expected-note@-1 {{no template parameter}} static_assert(v.val == 3); }; void test() { @@ -313,7 +313,7 @@ namespace classes { } template <template <class T2, int V3> class TT2> auto g(TT2<double, 1>) { - // expected-note@-1 {{too few template arguments for class template 'A'}} + // expected-note@-1 {{no template parameter}} return f(TT2<int, 2>()); } @@ -347,11 +347,11 @@ namespace packs { namespace t1 { template<template<int, int...> class> struct A {}; // expected-error@-1 {{non-type parameter of template template parameter cannot be narrowed from type 'int' to 'char'}} - // expected-note@-2 {{previous template template parameter is here}} + // expected-note@-2 {{template parameter is declared here}} - template<char> struct B; + template<char> struct B; // expected-note {{template parameter is declared here}} template struct A<B>; - // expected-note@-1 {{has different template parameters}} + // expected-note@-1 {{template template argument is incompatible}} } // namespace t1 namespace t2 { template<template<char, int...> class> struct A {}; @@ -361,11 +361,11 @@ namespace packs { namespace t3 { template<template<int...> class> struct A {}; // expected-error@-1 {{non-type parameter of template template parameter cannot be narrowed from type 'int' to 'char'}} - // expected-note@-2 {{previous template template parameter is here}} + // expected-note@-2 {{template parameter is declared here}} - template<char> struct B; + template<char> struct B; // expected-note {{template parameter is declared here}} template struct A<B>; - // expected-note@-1 {{has different template parameters}} + // expected-note@-1 {{template template argument is incompatible}} } // namespace t3 namespace t4 { template<template<char...> class> struct A {}; @@ -501,7 +501,7 @@ namespace constraints { // expected-note@-1 {{similar constraint expressions not considered equivalent}} namespace t1 { - template<template<C1, class... T1s> class TT1> // expected-note {{TT1' declared here}} + template<template<C1, class... T1s> class TT1> // expected-note {{template parameter is declared here}} struct A {}; template<D1, class T2> struct B {}; // expected-note {{'B' declared here}} template struct A<B>; @@ -513,7 +513,7 @@ namespace constraints { template struct A<B>; } // namespace t2 namespace t3 { - template<template<C1, class... T1s> class TT1> // expected-note {{'TT1' declared here}} + template<template<C1, class... T1s> class TT1> // expected-note {{template parameter is declared here}} struct A {}; template<C2, class T2> struct B {}; // expected-note {{'B' declared here}} template struct A<B>; @@ -521,7 +521,7 @@ namespace constraints { } // namespace t2 namespace t4 { // FIXME: This should be accepted. - template<template<C1... T1s> class TT1> // expected-note {{'TT1' declared here}} + template<template<C1... T1s> class TT1> // expected-note {{template parameter is declared here}} struct A {}; template<C1 T2> struct B {}; // expected-note {{'B' declared here}} template struct A<B>; @@ -529,14 +529,14 @@ namespace constraints { } // namespace t4 namespace t5 { // FIXME: This should be accepted - template<template<C2... T1s> class TT1> // expected-note {{'TT1' declared here}} + template<template<C2... T1s> class TT1> // expected-note {{template parameter is declared here}} struct A {}; template<C1 T2> struct B {}; // expected-note {{'B' declared here}} template struct A<B>; // expected-error@-1 {{'B' is more constrained than template template parameter 'TT1'}} } // namespace t5 namespace t6 { - template<template<C1... T1s> class TT1> // expected-note {{'TT1' declared here}} + template<template<C1... T1s> class TT1> // expected-note {{template parameter is declared here}} struct A {}; template<C2 T2> struct B {}; // expected-note {{'B' declared here}} template struct A<B>; @@ -555,14 +555,14 @@ namespace constraints { template struct A<B>; } // namespace t8 namespace t9 { - template<template<C1... T1s> class TT1> // expected-note {{'TT1' declared here}} + template<template<C1... T1s> class TT1> // expected-note {{template parameter is declared here}} struct A {}; template<D1 T2> struct B {}; // expected-note {{'B' declared here}} template struct A<B>; // expected-error@-1 {{'B' is more constrained than template template parameter 'TT1'}} } // namespace t9 namespace t10 { - template<template<class...> requires C1<int> class TT1> // expected-note {{'TT1' declared here}} + template<template<class...> requires C1<int> class TT1> // expected-note {{template parameter is declared here}} struct A {}; template<class> requires C2<int> struct B {}; // expected-note {{'B' declared here}} @@ -678,16 +678,16 @@ namespace nttp_inconsistent { template<class A, A B> struct X {}; // expected-error@-1 {{conflicting deduction 'C' against 'int' for parameter}} template<template<class C, int D> class TT> struct Y {}; - // expected-note@-1 {{previous template template parameter is here}} + // expected-note@-1 {{template parameter is declared here}} template struct Y<X>; - // expected-note@-1 {{has different template parameters}} + // expected-note@-1 {{template template argument is incompatible with its corresponding template template parameter}} } // namespace t1 namespace t2 { template<class A, A B = 0> struct X {}; // expected-error@-1 {{conflicting deduction 'C' against 'int' for parameter}} template<template<class C> class TT> struct Y {}; - // expected-note@-1 {{previous template template parameter is here}} + // expected-note@-1 {{template parameter is declared here}} template struct Y<X>; - // expected-note@-1 {{has different template parameters}} + // expected-note@-1 {{template template argument is incompatible with its corresponding template template parameter}} } // namespace t2 } // namespace nttp_inconsistent diff --git a/clang/test/SemaTemplate/dedup-types-builtin.cpp b/clang/test/SemaTemplate/dedup-types-builtin.cpp index fe6efd7..8e97894 100644 --- a/clang/test/SemaTemplate/dedup-types-builtin.cpp +++ b/clang/test/SemaTemplate/dedup-types-builtin.cpp @@ -134,7 +134,9 @@ constexpr int dedup_params_into_type_list(TypeList<__builtin_dedup_pack<T...>... static_assert(dedup_params_into_type_list(static_cast<TypeList<int,short,long>*>(nullptr), 1, short(1), 1, 1l, 1l) != 5); // expected-error {{static assertion failed}} \ // expected-note {{expression evaluates}} -template <class T, __builtin_dedup_pack<T, int>...> // expected-error 2{{expansions of '__builtin_dedup_pack' are not supported here}} +template <class T, __builtin_dedup_pack<T, int>...> +// expected-error@-1 2{{expansions of '__builtin_dedup_pack' are not supported here}} +// expected-note@-2 2{{template parameter is declared here}} struct InTemplateParams {}; InTemplateParams<int> itp1; InTemplateParams<int, 1, 2, 3, 4, 5> itp2; diff --git a/clang/test/SemaTemplate/default-arguments.cpp b/clang/test/SemaTemplate/default-arguments.cpp index 5ea34c0..fdf666b 100644 --- a/clang/test/SemaTemplate/default-arguments.cpp +++ b/clang/test/SemaTemplate/default-arguments.cpp @@ -1,12 +1,12 @@ // RUN: %clang_cc1 -fsyntax-only -verify %s // RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s -template<typename T, int N = 2> struct X; // expected-note{{template is declared here}} +template<typename T, int N = 2> struct X; // expected-note {{template parameter is declared here}} X<int, 1> *x1; X<int> *x2; -X<> *x3; // expected-error{{too few template arguments for class template 'X'}} +X<> *x3; // expected-error{{missing template argument for template parameter}} template<typename U = float, int M> struct X; @@ -20,6 +20,7 @@ template<class T> struct a { }; template<> struct a<int> { static const bool v = true; }; template<class T, bool = a<T>::v> struct p { }; // expected-error {{no member named 'v'}} + // expected-note@-1 {{template parameter is declared here}} template struct p<bool>; // expected-note {{in instantiation of default argument for 'p<bool>' required here}} template struct p<int>; @@ -50,12 +51,14 @@ template<typename T> struct X1 { }; template<typename T> struct X2 { template<typename U = typename X1<T>::type> // expected-error{{no type named 'type' in 'X1<int>'}} \ - // expected-error{{no type named 'type' in 'X1<char>'}} - struct Inner1 { }; // expected-note{{template is declared here}} + // expected-error{{no type named 'type' in 'X1<char>'}} \ + // expected-note {{template parameter is declared here}} + struct Inner1 { }; template<T Value = X1<T>::value> // expected-error{{no member named 'value' in 'X1<int>'}} \ - // expected-error{{no member named 'value' in 'X1<char>'}} - struct NonType1 { }; // expected-note{{template is declared here}} + // expected-error{{no member named 'value' in 'X1<char>'}} \ + // expected-note {{template parameter is declared here}} + struct NonType1 { }; template<T Value> struct Inner2 { }; @@ -74,10 +77,10 @@ struct X2 { X2<int> x2i; // expected-note{{in instantiation of template class 'X2<int>' requested here}} X2<int>::Inner1<float> x2iif; -X2<int>::Inner1<> x2bad; // expected-error{{too few template arguments for class template 'Inner1'}} +X2<int>::Inner1<> x2bad; // expected-error{{missing template argument for template parameter}} X2<int>::NonType1<'a'> x2_nontype1; -X2<int>::NonType1<> x2_nontype1_bad; // expected-error{{too few template arguments for class template 'NonType1'}} +X2<int>::NonType1<> x2_nontype1_bad; // expected-error{{missing template argument for template parameter}} // Check multi-level substitution into template type arguments X2<int>::Inner3<float>::VeryInner<> vi; @@ -112,12 +115,12 @@ template<typename T, template<typename> class X = T::template apply> int array4[is_same<X4<add_pointer>, X4<add_pointer, add_pointer::apply> >::value? 1 : -1]; -template<int> struct X5 {}; +template<int> struct X5 {}; // expected-note {{template parameter is declared here}} template<long long> struct X5b {}; template<typename T, template<T> class B = X5> // expected-error {{cannot be narrowed from type 'long long' to 'int'}} - // expected-note@-1 {{has different template parameters}} - // expected-note@-2 {{previous template template parameter is here}} + // expected-note@-1 {{template template argument is incompatible}} + // expected-note@-2 {{template parameter is declared here}} struct X6 {}; X6<int> x6a; diff --git a/clang/test/SemaTemplate/instantiate-member-pointers.cpp b/clang/test/SemaTemplate/instantiate-member-pointers.cpp index 8b6c2ef..e4974b2 100644 --- a/clang/test/SemaTemplate/instantiate-member-pointers.cpp +++ b/clang/test/SemaTemplate/instantiate-member-pointers.cpp @@ -18,7 +18,7 @@ template<typename T, typename Class> struct X2 { T f(Class &obj, T Class::*pm) { // expected-error{{to a reference}} \ // expected-error{{member pointer to void}} - return obj.*pm; + return obj.*pm; } }; @@ -40,12 +40,12 @@ typedef int Y::*IntMember; template<IntMember Member> struct X4 { X3<int, Y, Member> member; - + int &getMember(Y& y) { return y.*Member; } }; -int &get_X4(X4<&Y::x> x4, Y& y) { - return x4.getMember(y); +int &get_X4(X4<&Y::x> x4, Y& y) { + return x4.getMember(y); } template<IntMember Member> @@ -64,12 +64,12 @@ namespace ValueDepMemberPointer { template <typename T> void S<T>::instantiate() { int a[(int)sizeof(T)-42]; // expected-error{{array with a negative size}} } - S<int> s; + S<int> s; } namespace PR18192 { struct A { struct { int n; }; }; - template<int A::*> struct X {}; + template<int A::*> struct X {}; // expected-note {{template parameter is declared here}} constexpr int A::*p = &A::n; X<p> x; // expected-error{{not a pointer to member constant}} } diff --git a/clang/test/SemaTemplate/instantiate-template-template-parm.cpp b/clang/test/SemaTemplate/instantiate-template-template-parm.cpp index dce30aa2..601049a 100644 --- a/clang/test/SemaTemplate/instantiate-template-template-parm.cpp +++ b/clang/test/SemaTemplate/instantiate-template-template-parm.cpp @@ -20,17 +20,17 @@ apply<add_reference, int>::type ir = i; apply<add_reference, float>::type fr = i; // expected-error{{non-const lvalue reference to type 'float' cannot bind to a value of unrelated type 'int'}} // Template template parameters -template<int> struct B; +template<int> struct B; // expected-note {{template parameter is declared here}} template<typename T, template<T Value> class X> // expected-error{{cannot have type 'float'}} // expected-error@-1 {{cannot be narrowed from type 'long long' to 'int'}} - // expected-note@-2 {{previous template template parameter is here}} + // expected-note@-2 2{{template parameter is declared here}} struct X0 { }; X0<int, B> x0b1; X0<float, B> x0b2; // expected-note{{while substituting}} -X0<long long, B> x0b3; // expected-note {{has different template parameters}} +X0<long long, B> x0b3; // expected-note {{template template argument is incompatible}} template<template<int V> class TT> struct X1 { }; diff --git a/clang/test/SemaTemplate/instantiation-default-1.cpp b/clang/test/SemaTemplate/instantiation-default-1.cpp index 3e70a21..8ef9f12 100644 --- a/clang/test/SemaTemplate/instantiation-default-1.cpp +++ b/clang/test/SemaTemplate/instantiation-default-1.cpp @@ -1,7 +1,7 @@ // RUN: %clang_cc1 -fsyntax-only -verify %s template<typename T, typename U = const T> struct Def1; -template<> struct Def1<int> { +template<> struct Def1<int> { void foo(); }; @@ -22,9 +22,10 @@ void test_Def1(Def1<int, const int> *d1, Def1<const int, const int> *d2, template<typename T, // FIXME: bad error message below, needs better location info typename T2 = const T*> // expected-error{{'T2' declared as a pointer to a reference}} + // expected-note@-1 {{template parameter is declared here}} struct Def2; -template<> struct Def2<int> { +template<> struct Def2<int> { void foo(); }; @@ -40,11 +41,11 @@ template<> struct Def1<const int> { }; // expected-error{{redefinition of 'Def1< template<typename T, typename T2 = T&> struct Def3; -template<> struct Def3<int> { +template<> struct Def3<int> { void foo(); }; -template<> struct Def3<int&> { +template<> struct Def3<int&> { void bar(); }; @@ -83,7 +84,7 @@ template<typename R, typename Arg1, typename Arg2 = Arg1, typename FuncType = R (*)(Arg1, Arg2)> struct Def6; -template<> struct Def6<int, float> { +template<> struct Def6<int, float> { void foo(); }; @@ -91,7 +92,7 @@ template<> struct Def6<bool, int[5], float(double, double)> { void bar(); }; -bool test_Def6(Def6<int, float, float> *d6a, +bool test_Def6(Def6<int, float, float> *d6a, Def6<int, float, float, int (*)(float, float)> *d6b, Def6<bool, int[5], float(double, double), bool(*)(int*, float(*)(double, double))> *d6c) { diff --git a/clang/test/SemaTemplate/instantiation-default-2.cpp b/clang/test/SemaTemplate/instantiation-default-2.cpp index ffa77cf..e5db310 100644 --- a/clang/test/SemaTemplate/instantiation-default-2.cpp +++ b/clang/test/SemaTemplate/instantiation-default-2.cpp @@ -4,8 +4,7 @@ template<typename T, T Value> struct Constant; // FIXME: bad location precxx20-error@-1 {{a non-type template parameter cannot have type 'float'}} -// expected-note@-2 {{template parameter is declared here}} -// cxx20-note@-3 {{template parameter is declared here}} +// expected-note@-2 2{{template parameter is declared here}} Constant<int, 5> *c1; diff --git a/clang/test/SemaTemplate/instantiation-dependence.cpp b/clang/test/SemaTemplate/instantiation-dependence.cpp index 1a97dbf..d98d982 100644 --- a/clang/test/SemaTemplate/instantiation-dependence.cpp +++ b/clang/test/SemaTemplate/instantiation-dependence.cpp @@ -17,7 +17,8 @@ namespace PR24076 { } template<class T, - class = void_t<decltype(declval<T>() + 1)>> // expected-error {{invalid operands to binary expression}} + class = // expected-note {{template parameter is declared here}} + void_t<decltype(declval<T>() + 1)>> // expected-error {{invalid operands to binary expression}} struct bar {}; bar<s> bar; // expected-note {{in instantiation of}} diff --git a/clang/test/SemaTemplate/instantiation-depth-subst-2.cpp b/clang/test/SemaTemplate/instantiation-depth-subst-2.cpp index 2b519e9..66fd1af 100644 --- a/clang/test/SemaTemplate/instantiation-depth-subst-2.cpp +++ b/clang/test/SemaTemplate/instantiation-depth-subst-2.cpp @@ -2,5 +2,6 @@ template<int N> struct S { }; template<typename T> S<T() + T()> operator+(T, T); // expected-error {{instantiation exceeded maximum depth}} expected-note 2{{while substituting}} +// expected-note@-1 {{use -ftemplate-depth=N to increase recursive template instantiation depth}} S<0> s; int k = s + s; // expected-note {{while substituting}} diff --git a/clang/test/SemaTemplate/instantiation-depth-subst.cpp b/clang/test/SemaTemplate/instantiation-depth-subst.cpp index 062a8ed..17944bc 100644 --- a/clang/test/SemaTemplate/instantiation-depth-subst.cpp +++ b/clang/test/SemaTemplate/instantiation-depth-subst.cpp @@ -3,7 +3,8 @@ // PR9793 template<typename T> auto f(T t) -> decltype(f(t)); // \ // expected-error {{recursive template instantiation exceeded maximum depth of 2}} \ -// expected-note 2 {{while substituting}} +// expected-note 2 {{while substituting}} \ +// expected-note {{use -ftemplate-depth=N to increase recursive template instantiation depth}} struct S {}; int k = f(S{}); // expected-note {{while substituting}} diff --git a/clang/test/SemaTemplate/ms-unqualified-base-class.cpp b/clang/test/SemaTemplate/ms-unqualified-base-class.cpp index 5e926c5..d2b02e5 100644 --- a/clang/test/SemaTemplate/ms-unqualified-base-class.cpp +++ b/clang/test/SemaTemplate/ms-unqualified-base-class.cpp @@ -84,7 +84,7 @@ int main() { return I; } -template <typename Type, int TSize> class Vec {}; // expected-note {{template is declared here}} +template <typename Type, int TSize> class Vec {}; // expected-note {{template parameter is declared here}} template <int TDim> class Index : public Vec<int, TDim> { // after-error@+1 {{member initializer 'Vec' does not name a non-static data member or base class}} @@ -107,7 +107,7 @@ template <typename T> class Wrong : public Vec<T, 4> { template class Wrong<double>; template <typename T> class Wrong2 : public Vec<T, 4> { - Wrong2() : Vec<T>() {} // expected-error {{too few template arguments for class template 'Vec'}} + Wrong2() : Vec<T>() {} // expected-error {{missing template argument for template parameter}} }; template class Wrong2<double>; diff --git a/clang/test/SemaTemplate/nested-template.cpp b/clang/test/SemaTemplate/nested-template.cpp index b5da1b1..dbdf605 100644 --- a/clang/test/SemaTemplate/nested-template.cpp +++ b/clang/test/SemaTemplate/nested-template.cpp @@ -114,16 +114,16 @@ template<typename T> struct X2 { template<template<class U, T Value> class> // expected-error {{cannot have type 'float'}} // expected-error@-1 {{cannot be narrowed from type 'long long' to 'int'}} - // expected-note@-2 {{previous template template parameter is here}} + // expected-note@-2 {{template parameter is declared here}} struct Inner { }; }; -template<typename T, int Value> +template<typename T, int Value> // expected-note {{template parameter is declared here}} struct X2_arg; X2<int>::Inner<X2_arg> x2i1; X2<float> x2a; // expected-note{{instantiation}} -X2<long long>::Inner<X2_arg> x2i3; // expected-note {{has different template parameters}} +X2<long long>::Inner<X2_arg> x2i3; // expected-note {{template template argument is incompatible}} namespace PR10896 { template<typename TN> diff --git a/clang/test/SemaTemplate/partial-spec-instantiate.cpp b/clang/test/SemaTemplate/partial-spec-instantiate.cpp index 0b84df6..f171bf4 100644 --- a/clang/test/SemaTemplate/partial-spec-instantiate.cpp +++ b/clang/test/SemaTemplate/partial-spec-instantiate.cpp @@ -42,7 +42,7 @@ namespace WonkyAccess { } namespace rdar9169404 { - template<typename T, T N> struct X { }; + template<typename T, T N> struct X { }; // #rdar9169404-X template<bool C> struct X<bool, C> { typedef int type; }; @@ -50,6 +50,7 @@ namespace rdar9169404 { X<bool, -1>::type value; #if __cplusplus >= 201103L // expected-error@-2 {{non-type template argument evaluates to -1, which cannot be narrowed to type 'bool'}} + // expected-note@#rdar9169404-X {{template parameter is declared here}} #endif } diff --git a/clang/test/SemaTemplate/recovery-crash.cpp b/clang/test/SemaTemplate/recovery-crash.cpp index 9b106f1..0d8c7e6 100644 --- a/clang/test/SemaTemplate/recovery-crash.cpp +++ b/clang/test/SemaTemplate/recovery-crash.cpp @@ -26,13 +26,14 @@ namespace PR16134 { } namespace PR16225 { - template <typename T> void f(); + template <typename T> void f(); // #PR16225-f template <typename C> void g(C*) { struct LocalStruct : UnknownBase<Mumble, C> { }; // expected-error {{use of undeclared identifier 'Mumble'}} f<LocalStruct>(); #if __cplusplus <= 199711L // expected-warning@-2 {{template argument uses local type 'LocalStruct'}} // expected-note@-3 {{while substituting explicitly-specified template arguments}} + // expected-note@#PR16225-f {{template parameter is declared here}} #endif struct LocalStruct2 : UnknownBase<C> { }; // expected-error {{no template named 'UnknownBase'}} } diff --git a/clang/test/SemaTemplate/temp_arg.cpp b/clang/test/SemaTemplate/temp_arg.cpp index 538056a..9048744 100644 --- a/clang/test/SemaTemplate/temp_arg.cpp +++ b/clang/test/SemaTemplate/temp_arg.cpp @@ -1,10 +1,10 @@ // RUN: %clang_cc1 -fsyntax-only -verify=expected,precxx17 %std_cxx98-14 %s // RUN: %clang_cc1 -fsyntax-only -verify=expected,cxx17 %std_cxx17- %s -template<typename T, - int I, - template<typename> class TT> - class A; // precxx17-note 3 {{template is declared here}} \ - cxx17-note 2 {{template is declared here}} \ +template<typename T, + int I, + template<typename> class TT> // expected-note {{template parameter is declared here}} + class A; // precxx17-note 2 {{template is declared here}} \ + cxx17-note {{template is declared here}} \ cxx17-note {{candidate template ignored: couldn't infer template argument 'T'}} \ cxx17-note {{implicit deduction guide declared as 'template <typename T, int I, template <typename> class TT> A(A<T, I, TT>) -> A<T, I, TT>'}} \ cxx17-note {{candidate function template not viable: requires 1 argument, but 0 were provided}} \ @@ -15,7 +15,7 @@ template<typename> class X; A<int, 0, X> * a1; A<float, 1, X, double> *a2; // expected-error{{too many template arguments for class template 'A'}} -A<float, 1> *a3; // expected-error{{too few template arguments for class template 'A'}} +A<float, 1> *a3; // expected-error{{missing template argument for template parameter}} A a4; // precxx17-error{{use of class template 'A' requires template arguments}} \ cxx17-error{{no viable constructor or deduction guide for deduction of template arguments of 'A'}} diff --git a/clang/test/SemaTemplate/temp_arg_nontype.cpp b/clang/test/SemaTemplate/temp_arg_nontype.cpp index 7d2a010..e9194fb 100644 --- a/clang/test/SemaTemplate/temp_arg_nontype.cpp +++ b/clang/test/SemaTemplate/temp_arg_nontype.cpp @@ -1,5 +1,5 @@ // RUN: %clang_cc1 -fsyntax-only -std=c++98 -Wconversion -verify %s -template<int N> struct A; // expected-note 5{{template parameter is declared here}} +template<int N> struct A; // expected-note 6{{template parameter is declared here}} A<0> *a0; @@ -42,7 +42,7 @@ double g(double); // expected-note 2{{candidate function}} int h(int); float h2(float); -template<int fp(int)> struct A3; // expected-note 1{{template parameter is declared here}} +template<int fp(int)> struct A3; // expected-note 2{{template parameter is declared here}} A3<h> *a14_1; A3<&h> *a14_2; A3<f> *a14_3; @@ -61,7 +61,7 @@ A4<*X_volatile_ptr> *a15_2; // expected-error{{non-type template argument does n A4<y> *15_3; // expected-error{{non-type template parameter of reference type 'const X &' cannot bind to template argument of type 'struct Y'}} \ // FIXME: expected-error{{expected unqualified-id}} -template<int (&fr)(int)> struct A5; // expected-note{{template parameter is declared here}} +template<int (&fr)(int)> struct A5; // expected-note 2{{template parameter is declared here}} A5<h> *a16_1; A5<f> *a16_3; A5<h2> *a16_6; // expected-error{{non-type template parameter of reference type 'int (&)(int)' cannot bind to template argument of type 'float (float)'}} @@ -86,7 +86,7 @@ A6<&Z::baz> *a17_3; // expected-error-re{{non-type template argument of type 'do template<int Z::*pm> struct A7; // expected-note{{template parameter is declared here}} -template<int Z::*pm> struct A7c; +template<int Z::*pm> struct A7c; // expected-note{{template parameter is declared here}} A7<&Z::int_member> *a18_1; A7c<&Z::int_member> *a18_2; A7<&Z::float_member> *a18_3; // expected-error{{non-type template argument of type 'float Z::*' cannot be converted to a value of type 'int Z::*'}} @@ -444,7 +444,10 @@ namespace dependent_nested_partial_specialization { A<Y>::B<int, &n> ay; // expected-error {{undefined}} expected-note {{instantiation of}} template<template<typename> class X> struct C { - template<typename T, int N, int M> struct D; // expected-note {{here}} + template<typename T, int N, + int M // expected-note {{template parameter is declared here}} + > struct D; + // expected-note@-1 {{template is declared here}} template<typename T, X<T> N> struct D<T*, N, N + 1> {}; // expected-error {{type of specialized non-type template argument depends on}} }; C<X>::D<int*, 0, 1> cx; @@ -494,7 +497,12 @@ namespace dependent_backreference { Incomplete f(int); // expected-note 2{{here}} int f(short); - template<typename T, T Value, int(*)[sizeof(f(Value))]> struct X {}; // expected-error 2{{incomplete}} + template<typename T, T Value, + int(*)[ // expected-note 2{{template parameter is declared here}} + sizeof(f(Value)) // expected-error 2{{incomplete}} + ] + > struct X {}; + int arr[sizeof(int)]; // When checking this template-id, we must not treat 'Value' as having type // 'int'; its type is the dependent type 'T'. diff --git a/clang/test/SemaTemplate/temp_arg_nontype_cxx11.cpp b/clang/test/SemaTemplate/temp_arg_nontype_cxx11.cpp index 5752cba..32bb678 100644 --- a/clang/test/SemaTemplate/temp_arg_nontype_cxx11.cpp +++ b/clang/test/SemaTemplate/temp_arg_nontype_cxx11.cpp @@ -30,7 +30,7 @@ namespace Auto { namespace check_conversion_early { struct X {}; - template<int> struct A {}; + template<int> struct A {}; // expected-note {{template parameter is declared here}} template<X &x> struct A<x> {}; // expected-error {{not implicitly convertible}} struct Y { constexpr operator int() const { return 0; } }; diff --git a/clang/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp b/clang/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp index 9c25e26..55d1d56 100644 --- a/clang/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp +++ b/clang/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp @@ -1,6 +1,6 @@ // RUN: %clang_cc1 -fsyntax-only -verify -std=c++1z %s -template<typename T, T val> struct A {}; // expected-note 3{{template parameter is declared here}} +template<typename T, T val> struct A {}; // expected-note 15{{template parameter is declared here}} template<typename T, typename U> constexpr bool is_same = false; template<typename T> constexpr bool is_same<T, T> = true; @@ -254,8 +254,8 @@ namespace Auto { } namespace DecltypeAuto { - template<auto v> struct A { }; - template<decltype(auto) v> struct DA { }; + template<auto v> struct A { }; // expected-note {{template parameter is declared here}} + template<decltype(auto) v> struct DA { }; // expected-note {{template parameter is declared here}} template<auto&> struct R { }; auto n = 0; // expected-note + {{declared here}} @@ -448,7 +448,7 @@ namespace PR42108 { struct R {}; struct S { constexpr S() {} constexpr S(R) {} }; struct T { constexpr operator S() { return {}; } }; - template <const S &> struct A {}; // expected-note {{template parameter is declared here}} + template <const S &> struct A {}; // expected-note 3{{template parameter is declared here}} void f() { A<R{}>(); // expected-error {{would bind reference to a temporary}} A<S{}>(); // expected-error {{reference to temporary object}} diff --git a/clang/test/SemaTemplate/temp_arg_nontype_cxx20.cpp b/clang/test/SemaTemplate/temp_arg_nontype_cxx20.cpp index 8450ff0..2f029db 100644 --- a/clang/test/SemaTemplate/temp_arg_nontype_cxx20.cpp +++ b/clang/test/SemaTemplate/temp_arg_nontype_cxx20.cpp @@ -16,7 +16,7 @@ union U { int a, b; } u; int n; // expected-note 1+{{here}} // pointers to subobjects -template<int *> struct IntPtr {}; +template<int *> struct IntPtr {}; // expected-note 2{{template parameter is declared here}} using IPn = IntPtr<&n + 1>; using IPn = IntPtr<&n + 1>; @@ -30,7 +30,7 @@ using IP3 = IntPtr<s.n + 3>; using IP5 = IntPtr<&s.n[5]>; // expected-error {{not a constant expression}} expected-note {{cannot refer to element 5 of array of 3 elements}} -template<int &> struct IntRef {}; +template<int &> struct IntRef {}; // expected-note 4{{template parameter is declared here}} using IRn = IntRef<*(&n + 1)>; // expected-error {{not a constant expression}} expected-note {{dereferenced pointer past the end of 'n'}} using IRn = IntRef<*(&n + 1)>; // expected-error {{not a constant expression}} expected-note {{dereferenced pointer past the end of 'n'}} @@ -72,20 +72,20 @@ namespace ClassNTTP { static_assert(&id<A{1,3}> != &id<a>); int k = id<1>; // expected-error {{no viable conversion from 'int' to 'A'}} - // expected-note@#ClassNTTP1 {{passing argument to parameter 'a' here}} + // expected-note@#ClassNTTP1 {{template parameter is declared here}} struct B { constexpr B() {} constexpr B(int) = delete; // expected-note {{here}} }; - template<B> struct Q {}; // expected-note {{passing argument to parameter here}} + template<B> struct Q {}; // expected-note {{template parameter is declared here}} Q<1> q; // expected-error {{conversion function from 'int' to 'B' invokes a deleted function}} struct C { constexpr C() {} C(const C&) = delete; // expected-note {{here}} }; - template<C> struct R {}; // expected-note {{passing argument to parameter here}} + template<C> struct R {}; // expected-note {{template parameter is declared here}} constexpr C c; R<c> r; // expected-error {{call to deleted constructor}} } @@ -228,7 +228,7 @@ namespace UnnamedBitfield { // // FIXME: We shouldn't track a value for unnamed bit-fields, nor number // them when computing field indexes. - template <A> struct X {}; + template <A> struct X {}; // expected-note {{template parameter is declared here}} constexpr A a; using T = X<a>; using T = X<A{}>; @@ -238,7 +238,7 @@ namespace UnnamedBitfield { } namespace Temporary { - template<const int &> struct A {}; // expected-note {{template parameter is declared here}} + template<const int &> struct A {}; // expected-note 6{{template parameter is declared here}} A<0> a0; // expected-error {{conversion from 'int' to 'const int &' in converted constant expression would bind reference to a temporary}} A<(const int&)1> a1; // expected-error {{reference to temporary object is not allowed in a template argument}} @@ -254,18 +254,18 @@ namespace Temporary { X &&x = X{}; A<x.a[3]> a5; // expected-error {{reference to subobject of temporary object}} - template<const int*> struct B {}; + template<const int*> struct B {}; // expected-note 3{{template parameter is declared here}} B<&(int&)(int&&)0> b0; // expected-error {{pointer to temporary object}} B<&r3> b3; // expected-error {{pointer to temporary object}} B<&x.a[3]> b5; // expected-error {{pointer to subobject of temporary object}} struct C { const int *p[2]; }; - template<C> struct D {}; + template<C> struct D {}; // expected-note {{template parameter is declared here}} D<C{nullptr, &r3}> d; // expected-error {{pointer to temporary object}} } namespace StringLiteral { - template<decltype(auto)> struct Y {}; + template<decltype(auto)> struct Y {}; // expected-note 6{{template parameter is declared here}} Y<&"hello"> y1; // expected-error {{pointer to string literal}} Y<"hello"> y2; // expected-error {{reference to string literal}} Y<+"hello"> y3; // expected-error {{pointer to subobject of string literal}} @@ -278,7 +278,7 @@ namespace StringLiteral { } namespace TypeInfo { - template<decltype(auto)> struct Y {}; + template<decltype(auto)> struct Y {}; // expected-note 4{{template parameter is declared here}} Y<&typeid(int)> y1; // expected-error {{pointer to type_info object}} Y<typeid(int)> y2; // expected-error {{reference to type_info object}} @@ -289,7 +289,7 @@ namespace TypeInfo { } namespace Predefined { - template<decltype(auto)> struct Y {}; + template<decltype(auto)> struct Y {}; // expected-note 7{{template parameter is declared here}} struct A { const char *p; }; struct B { const char &r; }; diff --git a/clang/test/SemaTemplate/temp_arg_nontype_cxx2c.cpp b/clang/test/SemaTemplate/temp_arg_nontype_cxx2c.cpp index c4ac36e..9ecdd19 100644 --- a/clang/test/SemaTemplate/temp_arg_nontype_cxx2c.cpp +++ b/clang/test/SemaTemplate/temp_arg_nontype_cxx2c.cpp @@ -5,16 +5,16 @@ struct Test { int b = 42; }; -template <Test t> +template <Test t> // expected-note {{template parameter is declared here}} struct A { static constexpr auto a = t.a; static constexpr auto b = t.b; }; -template <auto N> +template <auto N> // expected-note {{template parameter is declared here}} struct Auto {}; -template <typename T, T elem> +template <typename T, T elem> // expected-note {{template parameter is declared here}} struct Explicit{}; struct L {}; @@ -57,8 +57,8 @@ void test() { DefaultParam3<> d3; } -template<auto n> struct B { /* ... */ }; -template<int i> struct C { /* ... */ }; +template<auto n> struct B { /* ... */ }; // expected-note 2{{template parameter is declared here}} +template<int i> struct C { /* ... */ }; // expected-note {{template parameter is declared here}} C<{ 42 }> c1; // expected-warning {{braces around scalar initializer}} struct J1 { @@ -129,6 +129,7 @@ namespace error_on_type_instantiation { // expected-note@-1 {{candidate function has been explicitly deleted}} template<class T, decltype(f(T()))> struct X {}; // expected-error@-1 {{call to deleted function 'f'}} + // expected-note@-2 {{template parameter is declared here}} template<class T> void g() { X<T, 0> x; } // expected-note@-1 {{while substituting prior template arguments into non-type template parameter [with T = int]}} template void g<int>(); diff --git a/clang/test/SemaTemplate/temp_arg_template.cpp b/clang/test/SemaTemplate/temp_arg_template.cpp index 73fa57b..b4b442c 100644 --- a/clang/test/SemaTemplate/temp_arg_template.cpp +++ b/clang/test/SemaTemplate/temp_arg_template.cpp @@ -2,13 +2,13 @@ // RUN: %clang_cc1 -fsyntax-only -verify=expected,cxx17 -std=c++17 %s template<template<typename T> class X> struct A; // #A -// expected-note@-1 2{{previous template template parameter is here}} +// expected-note@-1 3{{template parameter is declared here}} -template<template<typename T, int I> class X> struct B; // expected-note{{previous template template parameter is here}} +template<template<typename T, int I> class X> struct B; // expected-note{{template parameter is declared here}} template<template<int I> class X> struct C; // expected-error@-1 {{conversion from 'int' to 'const int &' in converted constant expression would bind reference to a temporary}} -// expected-note@-2 {{previous template template parameter is here}} +// expected-note@-2 {{template parameter is declared here}} template<class> struct X; // expected-note {{template is declared here}} template<int N> struct Y; // expected-note {{template parameter is declared here}} @@ -18,7 +18,10 @@ template<const int &N> struct Yref; // expected-note {{template parameter is dec namespace N { template<class> struct Z; } -template<class, class> struct TooMany; // expected-note{{template is declared here}} +template< + class, + class> // expected-note {{template parameter is declared here}} +struct TooMany; A<X> *a1; @@ -26,14 +29,14 @@ A<N::Z> *a2; A< ::N::Z> *a3; A<Y> *a4; // expected-error@#A {{template argument for non-type template parameter must be an expression}} - // expected-note@-1 {{different template parameters}} -A<TooMany> *a5; // expected-error {{too few template arguments for class template 'TooMany'}} - // expected-note@-1 {{different template parameters}} + // expected-note@-1 {{template template argument is incompatible}} +A<TooMany> *a5; // expected-error@#A {{no template parameter in this template template parameter}} + // expected-note@-1 {{template template argument is incompatible}} B<X> *a6; // expected-error {{too many template arguments for class template 'X'}} - // expected-note@-1 {{different template parameters}} + // expected-note@-1 {{template template argument is incompatible}} C<Y> *a7; C<Ylong> *a8; -C<Yref> *a9; // expected-note {{different template parameters}} +C<Yref> *a9; // expected-note {{template template argument is incompatible}} template<typename T> void f(int); @@ -109,7 +112,7 @@ void foo() { namespace CheckDependentNonTypeParamTypes { template<template<typename T, typename U, T v> class X> struct A { - // expected-note@-1 {{previous template template parameter is here}} + // expected-note@-1 2{{template parameter is declared here}} void f() { X<int, void*, 3> x; } @@ -128,7 +131,7 @@ namespace CheckDependentNonTypeParamTypes { }; // FIXME: This should probably be rejected, but the rules are at best unclear. - A<B> ab; // expected-note {{different template parameters}} + A<B> ab; // expected-note {{template template argument is incompatible}} void use() { ab.f(); @@ -138,6 +141,7 @@ namespace CheckDependentNonTypeParamTypes { template<class> struct C { template<class T, T V> struct D {}; + // expected-note@-1 {{template parameter is declared here}} using T = D<char, 1234>; // expected-error@-1 {{evaluates to 1234, which cannot be narrowed to type 'char'}} }; diff --git a/clang/test/SemaTemplate/temp_arg_template_p0522.cpp b/clang/test/SemaTemplate/temp_arg_template_p0522.cpp index 60d98a6..2b18a9f 100644 --- a/clang/test/SemaTemplate/temp_arg_template_p0522.cpp +++ b/clang/test/SemaTemplate/temp_arg_template_p0522.cpp @@ -1,8 +1,6 @@ // RUN: %clang_cc1 -fsyntax-only -verify -std=c++20 %s -// expected-note@temp_arg_template_p0522.cpp:* 1+{{template is declared here}} // expected-note@temp_arg_template_p0522.cpp:* 1+{{template parameter is declared here}} -// expected-note@temp_arg_template_p0522.cpp:* 1+{{previous template template parameter is here}} template<template<int> typename> struct Ti; // #Ti template<template<int...> typename> struct TPi; // #TPi @@ -34,14 +32,14 @@ namespace IntParam { Ti<iDi>, Ti<Pi>, Ti<iDt>>; - using err1 = Ti<ii>; // expected-error {{too few template arguments for class template 'ii'}} - // expected-note@-1 {{different template parameters}} - using err2 = Ti<iiPi>; // expected-error {{too few template arguments for class template 'iiPi'}} - // expected-note@-1 {{different template parameters}} + using err1 = Ti<ii>; // expected-error@#Ti {{no template parameter in this template template parameter}} + // expected-note@-1 {{template template argument is incompatible}} + using err2 = Ti<iiPi>; // expected-error@#Ti {{no template parameter in this template template parameter}} + // expected-note@-1 {{template template argument is incompatible}} using err3 = Ti<t0>; // expected-error@#Ti {{template argument for template type parameter must be a type}} - // expected-note@-1 {{different template parameters}} - using err4 = Ti<it>; // expected-error {{too few template arguments for class template 'it'}} - // expected-note@-1 {{different template parameters}} + // expected-note@-1 {{template template argument is incompatible}} + using err4 = Ti<it>; // expected-error@#Ti {{no template parameter in this template template parameter}} + // expected-note@-1 {{template template argument is incompatible}} } // These are accepted by the backwards-compatibility "parameter pack in @@ -50,11 +48,11 @@ namespace IntPackParam { using ok = TPi<Pi>; using ok_compat = Pt<TPi<i>, TPi<iDi>, TPi<ii>, TPi<iiPi>>; using err1 = TPi<t0>; // expected-error@#TPi {{template argument for template type parameter must be a type}} - // expected-note@-1 {{different template parameters}} + // expected-note@-1 {{template template argument is incompatible}} using err2 = TPi<iDt>; // expected-error@#TPi {{template argument for template type parameter must be a type}} - // expected-note@-1 {{different template parameters}} + // expected-note@-1 {{template template argument is incompatible}} using err3 = TPi<it>; // expected-error@#TPi {{template argument for template type parameter must be a type}} - // expected-note@-1 {{different template parameters}} + // expected-note@-1 {{template template argument is incompatible}} } namespace IntAndPackParam { @@ -65,19 +63,19 @@ namespace IntAndPackParam { namespace DependentType { using ok = Pt<tT0<int, i>, tT0<int, iDi>>; - using err1 = tT0<int, ii>; // expected-error {{too few template arguments for class template 'ii'}} - // expected-note@-1 {{different template parameters}} + using err1 = tT0<int, ii>; // expected-error@#tT0 {{no template parameter in this template template parameter}} + // expected-note@-1 {{template template argument is incompatible}} using err2 = tT0<short, i>; using err2a = tT0<long long, i>; // expected-error@#tT0 {{cannot be narrowed from type 'long long' to 'int'}} - // expected-note@-1 {{different template parameters}} + // expected-note@-1 {{template template argument is incompatible}} using err2b = tT0<void*, i>; // expected-error@#tT0 {{value of type 'void *' is not implicitly convertible to 'int'}} - // expected-note@-1 {{different template parameters}} + // expected-note@-1 {{template template argument is incompatible}} using err3 = tT0<short, t0>; // expected-error@#tT0 {{template argument for template type parameter must be a type}} - // expected-note@-1 {{different template parameters}} + // expected-note@-1 {{template template argument is incompatible}} using ok2 = Tt0<t0>; using err4 = Tt0<it>; // expected-error@#Tt0 {{template argument for non-type template parameter must be an expression}} - // expected-note@-1 {{different template parameters}} + // expected-note@-1 {{template template argument is incompatible}} } namespace Auto { @@ -94,22 +92,22 @@ namespace Auto { TInt<Auto> ia; TInt<AutoPtr> iap; // expected-error@#TInt {{non-type template parameter '' with type 'auto *' has incompatible initializer of type 'int'}} - // expected-note@-1 {{different template parameters}} + // expected-note@-1 {{template template argument is incompatible}} TInt<DecltypeAuto> ida; TInt<Int> ii; TInt<IntPtr> iip; // expected-error@#TInt {{conversion from 'int' to 'int *' is not allowed in a converted constant expression}} - // expected-note@-1 {{different template parameters}} + // expected-note@-1 {{template template argument is incompatible}} TIntPtr<Auto> ipa; TIntPtr<AutoPtr> ipap; TIntPtr<DecltypeAuto> ipda; TIntPtr<Int> ipi; // expected-error@#TIntPtr {{value of type 'int *' is not implicitly convertible to 'int'}} - // expected-note@-1 {{different template parameters}} + // expected-note@-1 {{template template argument is incompatible}} TIntPtr<IntPtr> ipip; TAuto<Auto> aa; TAuto<AutoPtr> aap; // expected-error@#TAuto {{non-type template parameter '' with type 'auto *' has incompatible initializer of type 'auto'}} - // expected-note@-1 {{different template parameters}} + // expected-note@-1 {{template template argument is incompatible}} TAuto<Int> ai; // FIXME: ill-formed (?) TAuto<IntPtr> aip; // FIXME: ill-formed (?) @@ -131,7 +129,7 @@ namespace Auto { // parameters. TDecltypeAuto<Auto> daa; TDecltypeAuto<AutoPtr> daap; // expected-error@#TDecltypeAuto {{non-type template parameter '' with type 'auto *' has incompatible initializer of type 'decltype(auto)'}} - // expected-note@-1 {{different template parameters}} + // expected-note@-1 {{template template argument is incompatible}} int n; template<auto A, decltype(A) B = &n> struct SubstFailure; @@ -160,11 +158,10 @@ namespace GH101394 { } // namespace t1 namespace t2 { template<template<Y> class> struct A {}; // #A - template<X> struct B; // #B + template<X> struct B; template struct A<B>; // expected-error@#A {{no viable conversion from 'const Y' to 'X'}} - // expected-note@-2 {{different template parameters}} + // expected-note@-2 {{template template argument is incompatible}} // expected-note@#X 2{{not viable}} - // expected-note@#B {{passing argument to parameter here}} } // namespace t2 } // namespace GH101394 diff --git a/clang/test/SemaTemplate/temp_arg_type.cpp b/clang/test/SemaTemplate/temp_arg_type.cpp index 392d257..a0d2bc3 100644 --- a/clang/test/SemaTemplate/temp_arg_type.cpp +++ b/clang/test/SemaTemplate/temp_arg_type.cpp @@ -1,9 +1,12 @@ // RUN: %clang_cc1 -fsyntax-only -verify %s -// RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s +// RUN: %clang_cc1 -fsyntax-only -verify=expected,cxx98 -std=c++98 %s // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s // RUN: %clang_cc1 -fsyntax-only -verify -std=c++1z %s -template<typename T> class A; // expected-note 2 {{template parameter is declared here}} expected-note{{template is declared here}} +template<typename T> class A; +// expected-note@-1 4{{template parameter is declared here}} +// cxx98-note@-2 2{{template parameter is declared here}} +// expected-note@-3 {{template is declared here}} // [temp.arg.type]p1 A<0> *a1; // expected-error{{template argument for template type parameter must be a type}} |