зеркало из https://github.com/microsoft/clang.git
Diagnose the presence of storage-class-specifiers on explicit
instantiations and specializations. Fixes <rdar://problem/9126453> and PR8700. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@131802 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
4337dc7760
Коммит
e885e188b2
|
@ -1827,6 +1827,8 @@ def err_not_class_template_specialization : Error<
|
|||
"parameter}0">;
|
||||
def err_function_specialization_in_class : Error<
|
||||
"cannot specialize a function %0 within class scope">;
|
||||
def err_explicit_specialization_storage_class : Error<
|
||||
"explicit specialization cannot have a storage class">;
|
||||
|
||||
// C++ class template specializations and out-of-line definitions
|
||||
def err_template_spec_needs_header : Error<
|
||||
|
@ -1983,6 +1985,8 @@ def err_explicit_instantiation_requires_name : Error<
|
|||
"explicit instantiation declaration requires a name">;
|
||||
def err_explicit_instantiation_of_typedef : Error<
|
||||
"explicit instantiation of typedef %0">;
|
||||
def err_explicit_instantiation_storage_class : Error<
|
||||
"explicit instantiation cannot have a storage class">;
|
||||
def err_explicit_instantiation_not_known : Error<
|
||||
"explicit instantiation of %0 does not refer to a function template, member "
|
||||
"function, member class, or static data member">;
|
||||
|
|
|
@ -4595,6 +4595,16 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
|
|||
(HasExplicitTemplateArgs ? &TemplateArgs : 0),
|
||||
Previous))
|
||||
NewFD->setInvalidDecl();
|
||||
|
||||
// C++ [dcl.stc]p1:
|
||||
// A storage-class-specifier shall not be specified in an explicit
|
||||
// specialization (14.7.3)
|
||||
if (SC != SC_None) {
|
||||
Diag(NewFD->getLocation(),
|
||||
diag::err_explicit_specialization_storage_class)
|
||||
<< FixItHint::CreateRemoval(D.getDeclSpec().getStorageClassSpecLoc());
|
||||
}
|
||||
|
||||
} else if (isExplicitSpecialization && isa<CXXMethodDecl>(NewFD)) {
|
||||
if (CheckMemberSpecialization(NewFD, Previous))
|
||||
NewFD->setInvalidDecl();
|
||||
|
|
|
@ -5377,7 +5377,7 @@ Sema::CheckFunctionTemplateSpecialization(FunctionDecl *FD,
|
|||
SpecInfo->getPointOfInstantiation(),
|
||||
HasNoEffect))
|
||||
return true;
|
||||
|
||||
|
||||
// Mark the prior declaration as an explicit specialization, so that later
|
||||
// clients know that this is an explicit specialization.
|
||||
if (!isFriend) {
|
||||
|
@ -5397,7 +5397,8 @@ Sema::CheckFunctionTemplateSpecialization(FunctionDecl *FD,
|
|||
TemplArgs, /*InsertPos=*/0,
|
||||
SpecInfo->getTemplateSpecializationKind(),
|
||||
TemplArgsAsWritten);
|
||||
|
||||
FD->setStorageClass(Specialization->getStorageClass());
|
||||
|
||||
// The "previous declaration" for this function template specialization is
|
||||
// the prior function template specialization.
|
||||
Previous.clear();
|
||||
|
@ -5998,11 +5999,20 @@ DeclResult Sema::ActOnExplicitInstantiation(Scope *S,
|
|||
if (R.isNull())
|
||||
return true;
|
||||
|
||||
// C++ [dcl.stc]p1:
|
||||
// A storage-class-specifier shall not be specified in [...] an explicit
|
||||
// instantiation (14.7.2) directive.
|
||||
if (D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_typedef) {
|
||||
// Cannot explicitly instantiate a typedef.
|
||||
Diag(D.getIdentifierLoc(), diag::err_explicit_instantiation_of_typedef)
|
||||
<< Name;
|
||||
return true;
|
||||
} else if (D.getDeclSpec().getStorageClassSpec()
|
||||
!= DeclSpec::SCS_unspecified) {
|
||||
// Complain about then remove the storage class specifier.
|
||||
Diag(D.getIdentifierLoc(), diag::err_explicit_instantiation_storage_class)
|
||||
<< FixItHint::CreateRemoval(D.getDeclSpec().getStorageClassSpecLoc());
|
||||
|
||||
D.getMutableDeclSpec().ClearStorageClassSpecs();
|
||||
}
|
||||
|
||||
// C++0x [temp.explicit]p1:
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
// RUN: %clang_cc1 -fsyntax-only -verify %s
|
||||
|
||||
// A storage-class-specifier shall not be specified in an explicit
|
||||
// specialization (14.7.3) or an explicit instantiation (14.7.2)
|
||||
// directive.
|
||||
template<typename T> void f(T) {}
|
||||
template<typename T> static void g(T) {}
|
||||
|
||||
|
||||
template<> static void f<int>(int); // expected-error{{explicit specialization cannot have a storage class}}
|
||||
template static void f<float>(float); // expected-error{{explicit instantiation cannot have a storage class}}
|
||||
|
||||
template<> void f<double>(double);
|
||||
template void f<long>(long);
|
||||
|
||||
template<> static void g<int>(int); // expected-error{{explicit specialization cannot have a storage class}}
|
||||
template static void g<float>(float); // expected-error{{explicit instantiation cannot have a storage class}}
|
||||
|
||||
template<> void g<double>(double);
|
||||
template void g<long>(long);
|
||||
|
||||
template<typename T>
|
||||
struct X {
|
||||
static int value;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
int X<T>::value = 17;
|
||||
|
||||
template static int X<int>::value; // expected-error{{explicit instantiation cannot have a storage class}}
|
||||
|
||||
template<> static int X<float>::value; // expected-error{{'static' can only be specified inside the class definition}}
|
Загрузка…
Ссылка в новой задаче