Diagnose attempts to write a templated data member, from Stepan

Dyatkovskiy! Fixes PR10896.

llvm-svn: 140250
This commit is contained in:
Douglas Gregor 2011-09-21 14:40:46 +00:00
parent bc9ba30158
commit 7c26c04ba9
3 changed files with 44 additions and 3 deletions

View File

@ -1947,6 +1947,9 @@ def err_template_template_parm_no_parms : Error<
def err_template_variable : Error<"variable %0 declared as a template">;
def err_template_variable_noparams : Error<
"extraneous 'template<>' in declaration of variable %0">;
def err_template_member : Error<"member %0 declared as a template">;
def err_template_member_noparams : Error<
"extraneous 'template<>' in declaration of member %0">;
def err_template_tag_noparams : Error<
"extraneous 'template<>' in declaration of %0 %1">;
def err_template_decl_ref : Error<

View File

@ -1121,6 +1121,30 @@ Sema::ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS, Declarator &D,
if (isInstField) {
CXXScopeSpec &SS = D.getCXXScopeSpec();
// FIXME: Check that the name is an identifier!
IdentifierInfo *II = Name.getAsIdentifierInfo();
// Member field could not be with "template" keyword.
// So TemplateParameterLists should be empty in this case.
if (TemplateParameterLists.size()) {
TemplateParameterList* TemplateParams = TemplateParameterLists.get()[0];
if (TemplateParams->size()) {
// There is no such thing as a member field template.
Diag(D.getIdentifierLoc(), diag::err_template_member)
<< II
<< SourceRange(TemplateParams->getTemplateLoc(),
TemplateParams->getRAngleLoc());
} else {
// There is an extraneous 'template<>' for this member.
Diag(TemplateParams->getTemplateLoc(),
diag::err_template_member_noparams)
<< II
<< SourceRange(TemplateParams->getTemplateLoc(),
TemplateParams->getRAngleLoc());
}
return 0;
}
if (SS.isSet() && !SS.isInvalid()) {
// The user provided a superfluous scope specifier inside a class
// definition:
@ -1138,9 +1162,7 @@ Sema::ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS, Declarator &D,
SS.clear();
}
// FIXME: Check for template parameters!
// FIXME: Check that the name is an identifier!
Member = HandleField(S, cast<CXXRecordDecl>(CurContext), Loc, D, BitWidth,
HasDeferredInit, AS);
assert(Member && "HandleField never returns null");

View File

@ -125,4 +125,20 @@ X2<int>::Inner<X2_arg> x2i1;
X2<float> x2a; // expected-note{{instantiation}}
X2<long>::Inner<X2_arg> x2i3; // expected-error{{template template argument has different}}
namespace PR10896 {
template<typename TN>
class Foo {
public:
void foo() {}
private:
template<typename T>
T SomeField; // expected-error {{member 'SomeField' declared as a template}}
};
void g() {
Foo<int> f;
f.foo();
}
}