зеркало из https://github.com/microsoft/clang.git
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:
Родитель
773d847fbe
Коммит
e389585f8a
|
@ -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
|
||||
|
|
Загрузка…
Ссылка в новой задаче