Author: rsmith Date: Fri Jun 14 13:01:54 2019 New Revision: 363447 URL: http://llvm.org/viewvc/llvm-project?rev=363447&view=rev Log: PR42071: Reject weird names for non-type template parameters.
Also reject default arguments appearing in invalid locations. Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td cfe/trunk/include/clang/Sema/Sema.h cfe/trunk/lib/Sema/SemaDecl.cpp cfe/trunk/lib/Sema/SemaTemplate.cpp cfe/trunk/test/Parser/cxx-template-decl.cpp Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=363447&r1=363446&r2=363447&view=diff ============================================================================== --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original) +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Fri Jun 14 13:01:54 2019 @@ -250,6 +250,8 @@ def err_bad_variable_name : Error< "%0 cannot be the name of a variable or data member">; def err_bad_parameter_name : Error< "%0 cannot be the name of a parameter">; +def err_bad_parameter_name_template_id : Error< + "parameter name cannot have template arguments">; def err_parameter_name_omitted : Error<"parameter name omitted">; def err_anyx86_interrupt_attribute : Error< "%select{x86|x86-64}0 'interrupt' attribute only applies to functions that " Modified: cfe/trunk/include/clang/Sema/Sema.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=363447&r1=363446&r2=363447&view=diff ============================================================================== --- cfe/trunk/include/clang/Sema/Sema.h (original) +++ cfe/trunk/include/clang/Sema/Sema.h Fri Jun 14 13:01:54 2019 @@ -2083,7 +2083,9 @@ public: QualType NewT, QualType OldT); void CheckMain(FunctionDecl *FD, const DeclSpec &D); void CheckMSVCRTEntryPoint(FunctionDecl *FD); - Attr *getImplicitCodeSegOrSectionAttrForFunction(const FunctionDecl *FD, bool IsDefinition); + Attr *getImplicitCodeSegOrSectionAttrForFunction(const FunctionDecl *FD, + bool IsDefinition); + void CheckFunctionOrTemplateParamDeclarator(Scope *S, Declarator &D); Decl *ActOnParamDeclarator(Scope *S, Declarator &D); ParmVarDecl *BuildParmVarDeclForTypedef(DeclContext *DC, SourceLocation Loc, Modified: cfe/trunk/lib/Sema/SemaDecl.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=363447&r1=363446&r2=363447&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaDecl.cpp (original) +++ cfe/trunk/lib/Sema/SemaDecl.cpp Fri Jun 14 13:01:54 2019 @@ -12453,6 +12453,45 @@ void Sema::ActOnDocumentableDecls(ArrayR } } +/// Common checks for a parameter-declaration that should apply to both function +/// parameters and non-type template parameters. +void Sema::CheckFunctionOrTemplateParamDeclarator(Scope *S, Declarator &D) { + // Check that there are no default arguments inside the type of this + // parameter. + if (getLangOpts().CPlusPlus) + CheckExtraCXXDefaultArguments(D); + + // Parameter declarators cannot be qualified (C++ [dcl.meaning]p1). + if (D.getCXXScopeSpec().isSet()) { + Diag(D.getIdentifierLoc(), diag::err_qualified_param_declarator) + << D.getCXXScopeSpec().getRange(); + } + + // [dcl.meaning]p1: An unqualified-id occurring in a declarator-id shall be a + // simple identifier except [...irrelevant cases...]. + switch (D.getName().getKind()) { + case UnqualifiedIdKind::IK_Identifier: + break; + + case UnqualifiedIdKind::IK_OperatorFunctionId: + case UnqualifiedIdKind::IK_ConversionFunctionId: + case UnqualifiedIdKind::IK_LiteralOperatorId: + case UnqualifiedIdKind::IK_ConstructorName: + case UnqualifiedIdKind::IK_DestructorName: + case UnqualifiedIdKind::IK_ImplicitSelfParam: + case UnqualifiedIdKind::IK_DeductionGuideName: + Diag(D.getIdentifierLoc(), diag::err_bad_parameter_name) + << GetNameForDeclarator(D).getName(); + break; + + case UnqualifiedIdKind::IK_TemplateId: + case UnqualifiedIdKind::IK_ConstructorTemplateId: + // GetNameForDeclarator would not produce a useful name in this case. + Diag(D.getIdentifierLoc(), diag::err_bad_parameter_name_template_id); + break; + } +} + /// ActOnParamDeclarator - Called from Parser::ParseFunctionDeclarator() /// to introduce parameters into function prototype scope. Decl *Sema::ActOnParamDeclarator(Scope *S, Declarator &D) { @@ -12493,34 +12532,13 @@ Decl *Sema::ActOnParamDeclarator(Scope * DiagnoseFunctionSpecifiers(DS); + CheckFunctionOrTemplateParamDeclarator(S, D); + TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S); QualType parmDeclType = TInfo->getType(); - if (getLangOpts().CPlusPlus) { - // Check that there are no default arguments inside the type of this - // parameter. - CheckExtraCXXDefaultArguments(D); - - // Parameter declarators cannot be qualified (C++ [dcl.meaning]p1). - if (D.getCXXScopeSpec().isSet()) { - Diag(D.getIdentifierLoc(), diag::err_qualified_param_declarator) - << D.getCXXScopeSpec().getRange(); - D.getCXXScopeSpec().clear(); - } - } - - // Ensure we have a valid name - IdentifierInfo *II = nullptr; - if (D.hasName()) { - II = D.getIdentifier(); - if (!II) { - Diag(D.getIdentifierLoc(), diag::err_bad_parameter_name) - << GetNameForDeclarator(D).getName(); - D.setInvalidType(true); - } - } - // Check for redeclaration of parameters, e.g. int foo(int x, int x); + IdentifierInfo *II = D.getIdentifier(); if (II) { LookupResult R(*this, II, D.getIdentifierLoc(), LookupOrdinaryName, ForVisibleRedeclaration); Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=363447&r1=363446&r2=363447&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaTemplate.cpp (original) +++ cfe/trunk/lib/Sema/SemaTemplate.cpp Fri Jun 14 13:01:54 2019 @@ -1181,6 +1181,8 @@ NamedDecl *Sema::ActOnNonTypeTemplatePar Invalid = true; } + CheckFunctionOrTemplateParamDeclarator(S, D); + IdentifierInfo *ParamName = D.getIdentifier(); bool IsParameterPack = D.hasEllipsis(); NonTypeTemplateParmDecl *Param = NonTypeTemplateParmDecl::Create( Modified: cfe/trunk/test/Parser/cxx-template-decl.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/cxx-template-decl.cpp?rev=363447&r1=363446&r2=363447&view=diff ============================================================================== --- cfe/trunk/test/Parser/cxx-template-decl.cpp (original) +++ cfe/trunk/test/Parser/cxx-template-decl.cpp Fri Jun 14 13:01:54 2019 @@ -253,3 +253,11 @@ namespace class_scope_instantiation { void f(double); }; } + +namespace PR42071 { + template<int SomeTemplateName<void>> struct A; // expected-error {{parameter name cannot have template arguments}} + template<int operator+> struct B; // expected-error {{'operator+' cannot be the name of a parameter}} + struct Q {}; + template<int Q::N> struct C; // expected-error {{parameter declarator cannot be qualified}} + template<int f(int a = 0)> struct D; // expected-error {{default arguments can only be specified for parameters in a function declaration}} +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits