Diagnose attempt to mark function-local declarations as __module_private__.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@139519 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Douglas Gregor 2011-09-12 18:37:38 +00:00
Родитель 773d847fbe
Коммит e389585f8a
3 изменённых файлов: 51 добавлений и 7 удалений

Просмотреть файл

@ -4725,6 +4725,12 @@ def err_module_private_follows_public : Error<
def err_module_private_specialization : Error<
"%select{template|partial|member}0 specialization cannot be "
"declared __module_private__">;
def err_module_private_local : Error<
"%select{local variable|parameter|typedef}0 %1 cannot be declared "
"__module_private__">;
def err_module_private_local_class : Error<
"local %select{struct|union|class|enum}0 cannot be declared "
"__module_private__">;
}
} // end of sema component.

Просмотреть файл

@ -2373,6 +2373,12 @@ Decl *Sema::ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS,
if (DS.isExplicitSpecified())
Diag(DS.getExplicitSpecLoc(), diag::warn_standalone_specifier) <<"explicit";
if (DS.isModulePrivateSpecified() &&
Tag && Tag->getDeclContext()->isFunctionOrMethod())
Diag(DS.getModulePrivateSpecLoc(), diag::err_module_private_local_class)
<< Tag->getTagKind()
<< FixItHint::CreateRemoval(DS.getModulePrivateSpecLoc());
// FIXME: Warn on useless attributes
return TagD;
@ -3818,6 +3824,10 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC,
}
}
// Set the lexical context. If the declarator has a C++ scope specifier, the
// lexical context will be different from the semantic context.
NewVD->setLexicalDeclContext(CurContext);
if (D.getDeclSpec().isThreadSpecified()) {
if (NewVD->hasLocalStorage())
Diag(D.getDeclSpec().getThreadSpecLoc(), diag::err_thread_non_global);
@ -3832,14 +3842,15 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC,
Diag(NewVD->getLocation(), diag::err_module_private_specialization)
<< 2
<< FixItHint::CreateRemoval(D.getDeclSpec().getModulePrivateSpecLoc());
else if (NewVD->hasLocalStorage())
Diag(NewVD->getLocation(), diag::err_module_private_local)
<< 0 << NewVD->getDeclName()
<< SourceRange(D.getDeclSpec().getModulePrivateSpecLoc())
<< FixItHint::CreateRemoval(D.getDeclSpec().getModulePrivateSpecLoc());
else
NewVD->setModulePrivate();
}
// Set the lexical context. If the declarator has a C++ scope specifier, the
// lexical context will be different from the semantic context.
NewVD->setLexicalDeclContext(CurContext);
// Handle attributes prior to checking for duplicates in MergeVarDecl
ProcessDeclAttributes(S, NewVD, D);
@ -6357,6 +6368,12 @@ Decl *Sema::ActOnParamDeclarator(Scope *S, Declarator &D) {
ProcessDeclAttributes(S, New, D);
if (D.getDeclSpec().isModulePrivateSpecified())
Diag(New->getLocation(), diag::err_module_private_local)
<< 1 << New->getDeclName()
<< SourceRange(D.getDeclSpec().getModulePrivateSpecLoc())
<< FixItHint::CreateRemoval(D.getDeclSpec().getModulePrivateSpecLoc());
if (New->hasAttr<BlocksAttr>()) {
Diag(New->getLocation(), diag::err_block_on_nonlocal);
}
@ -7021,8 +7038,15 @@ TypedefDecl *Sema::ParseTypedefDecl(Scope *S, Declarator &D, QualType T,
return NewTD;
}
if (D.getDeclSpec().isModulePrivateSpecified())
NewTD->setModulePrivate();
if (D.getDeclSpec().isModulePrivateSpecified()) {
if (CurContext->isFunctionOrMethod())
Diag(NewTD->getLocation(), diag::err_module_private_local)
<< 2 << NewTD->getDeclName()
<< SourceRange(D.getDeclSpec().getModulePrivateSpecLoc())
<< FixItHint::CreateRemoval(D.getDeclSpec().getModulePrivateSpecLoc());
else
NewTD->setModulePrivate();
}
// C++ [dcl.typedef]p8:
// If the typedef declaration defines an unnamed class (or
@ -7777,7 +7801,11 @@ CreateNewDecl:
<< FixItHint::CreateRemoval(ModulePrivateLoc);
else if (PrevDecl && !PrevDecl->isModulePrivate())
diagnoseModulePrivateRedeclaration(New, PrevDecl, ModulePrivateLoc);
else
// __module_private__ does not apply to local classes. However, we only
// diagnose this as an error when the declaration specifiers are
// freestanding. Here, we just ignore the __module_private__.
// foobar
else if (!SearchDC->isFunctionOrMethod())
New->setModulePrivate();
}

Просмотреть файл

@ -119,4 +119,14 @@ __module_private__ struct public_class<float> { }; // expected-error{{template s
template<typename T>
__module_private__ struct public_class<T *> { }; // expected-error{{partial specialization cannot be declared __module_private__}}
// Check for attempts to make parameters and variables with automatic
// storage module-private.
void local_var_private(__module_private__ int param) { // expected-error{{parameter 'param' cannot be declared __module_private__}}
__module_private__ struct Local { int x, y; } local; //expected-error{{local variable 'local' cannot be declared __module_private__}}
__module_private__ struct OtherLocal { int x; }; // expected-error{{local struct cannot be declared __module_private__}}
typedef __module_private__ int local_typedef; // expected-error{{typedef 'local_typedef' cannot be declared __module_private__}}
}
#endif