summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2019-06-14 20:01:54 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2019-06-14 20:01:54 +0000
commitda70fc0c5f5bb79fa46120710b7b66d1b7e7ca7e (patch)
treed7f567ca09b40a58236704dff545451e5145954a
parent7fa2b74e988e8da6a1d0c27d4c6567f26aec03e6 (diff)
downloadbcm5719-llvm-da70fc0c5f5bb79fa46120710b7b66d1b7e7ca7e.tar.gz
bcm5719-llvm-da70fc0c5f5bb79fa46120710b7b66d1b7e7ca7e.zip
PR42071: Reject weird names for non-type template parameters.
Also reject default arguments appearing in invalid locations. llvm-svn: 363447
-rw-r--r--clang/include/clang/Basic/DiagnosticSemaKinds.td2
-rw-r--r--clang/include/clang/Sema/Sema.h4
-rw-r--r--clang/lib/Sema/SemaDecl.cpp66
-rw-r--r--clang/lib/Sema/SemaTemplate.cpp2
-rw-r--r--clang/test/Parser/cxx-template-decl.cpp8
5 files changed, 57 insertions, 25 deletions
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 5b4e18673f2..94e819c5d59 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -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 "
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index b34f5c9196f..c6fddbbb9c6 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -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,
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index ce6fd412361..d346105e7ab 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -12453,6 +12453,45 @@ void Sema::ActOnDocumentableDecls(ArrayRef<Decl *> Group) {
}
}
+/// 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 *S, Declarator &D) {
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);
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 03240655ee3..74a891bcb70 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -1181,6 +1181,8 @@ NamedDecl *Sema::ActOnNonTypeTemplateParameter(Scope *S, Declarator &D,
Invalid = true;
}
+ CheckFunctionOrTemplateParamDeclarator(S, D);
+
IdentifierInfo *ParamName = D.getIdentifier();
bool IsParameterPack = D.hasEllipsis();
NonTypeTemplateParmDecl *Param = NonTypeTemplateParmDecl::Create(
diff --git a/clang/test/Parser/cxx-template-decl.cpp b/clang/test/Parser/cxx-template-decl.cpp
index 64c485fc0ec..07316782a83 100644
--- a/clang/test/Parser/cxx-template-decl.cpp
+++ b/clang/test/Parser/cxx-template-decl.cpp
@@ -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}}
+}
OpenPOWER on IntegriCloud