forked from OSchip/llvm-project
Sema: Variable definitions cannot be __attribute__((alias))
Things that are OK: extern int var1 __attribute((alias("v1"))); static int var2 __attribute((alias("v2"))); Things that are not OK: int var3 __attribute((alias("v3"))); extern int var4 __attribute((alias("v4"))) = 4; We choose to accpet: struct S { static int var5 __attribute((alias("v5"))); }; This code causes assertion failues in GCC 4.8 and ICC 13.0.1, we have no reason to reject it. This partially fixes PR22217. llvm-svn: 226436
This commit is contained in:
parent
0540f4141f
commit
2dc8146643
|
@ -345,6 +345,8 @@ def AddressSpace : TypeAttr {
|
||||||
def Alias : Attr {
|
def Alias : Attr {
|
||||||
let Spellings = [GCC<"alias">];
|
let Spellings = [GCC<"alias">];
|
||||||
let Args = [StringArgument<"Aliasee">];
|
let Args = [StringArgument<"Aliasee">];
|
||||||
|
let Subjects = SubjectList<[Function, GlobalVar], ErrorDiag,
|
||||||
|
"ExpectedFunctionGlobalVarMethodOrProperty">;
|
||||||
let Documentation = [Undocumented];
|
let Documentation = [Undocumented];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3902,10 +3902,8 @@ def warn_missing_variable_declarations : Warning<
|
||||||
def err_static_data_member_reinitialization :
|
def err_static_data_member_reinitialization :
|
||||||
Error<"static data member %0 already has an initializer">;
|
Error<"static data member %0 already has an initializer">;
|
||||||
def err_redefinition : Error<"redefinition of %0">;
|
def err_redefinition : Error<"redefinition of %0">;
|
||||||
def err_alias_after_tentative :
|
def err_alias_is_definition :
|
||||||
Error<"alias definition of %0 after tentative definition">;
|
Error<"definition %0 cannot also be an alias">;
|
||||||
def err_tentative_after_alias :
|
|
||||||
Error<"tentative definition of %0 after alias definition">;
|
|
||||||
def err_definition_of_implicitly_declared_member : Error<
|
def err_definition_of_implicitly_declared_member : Error<
|
||||||
"definition of implicitly declared %select{default constructor|copy "
|
"definition of implicitly declared %select{default constructor|copy "
|
||||||
"constructor|move constructor|copy assignment operator|move assignment "
|
"constructor|move constructor|copy assignment operator|move assignment "
|
||||||
|
|
|
@ -2219,18 +2219,8 @@ static void checkNewAttributesAfterDef(Sema &S, Decl *New, const Decl *Old) {
|
||||||
const Attr *NewAttribute = NewAttributes[I];
|
const Attr *NewAttribute = NewAttributes[I];
|
||||||
|
|
||||||
if (isa<AliasAttr>(NewAttribute)) {
|
if (isa<AliasAttr>(NewAttribute)) {
|
||||||
if (FunctionDecl *FD = dyn_cast<FunctionDecl>(New))
|
FunctionDecl *FD = cast<FunctionDecl>(New);
|
||||||
S.CheckForFunctionRedefinition(FD, cast<FunctionDecl>(Def));
|
S.CheckForFunctionRedefinition(FD, cast<FunctionDecl>(Def));
|
||||||
else {
|
|
||||||
VarDecl *VD = cast<VarDecl>(New);
|
|
||||||
unsigned Diag = cast<VarDecl>(Def)->isThisDeclarationADefinition() ==
|
|
||||||
VarDecl::TentativeDefinition
|
|
||||||
? diag::err_alias_after_tentative
|
|
||||||
: diag::err_redefinition;
|
|
||||||
S.Diag(VD->getLocation(), Diag) << VD->getDeclName();
|
|
||||||
S.Diag(Def->getLocation(), diag::note_previous_definition);
|
|
||||||
VD->setInvalidDecl();
|
|
||||||
}
|
|
||||||
++I;
|
++I;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -5103,6 +5093,18 @@ static void checkAttributesAfterMerging(Sema &S, NamedDecl &ND) {
|
||||||
if (ND.isExternallyVisible()) {
|
if (ND.isExternallyVisible()) {
|
||||||
S.Diag(Attr->getLocation(), diag::err_attribute_weakref_not_static);
|
S.Diag(Attr->getLocation(), diag::err_attribute_weakref_not_static);
|
||||||
ND.dropAttr<WeakRefAttr>();
|
ND.dropAttr<WeakRefAttr>();
|
||||||
|
ND.dropAttr<AliasAttr>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (auto *VD = dyn_cast<VarDecl>(&ND)) {
|
||||||
|
if (VD->hasInit()) {
|
||||||
|
if (const auto *Attr = VD->getAttr<AliasAttr>()) {
|
||||||
|
assert(VD->isThisDeclarationADefinition() &&
|
||||||
|
!VD->isExternallyVisible() && "Broken AliasAttr handled late!");
|
||||||
|
S.Diag(Attr->getLocation(), diag::err_alias_is_definition) << VD;
|
||||||
|
VD->dropAttr<AliasAttr>();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9617,18 +9619,6 @@ Sema::FinalizeDeclaration(Decl *ThisDecl) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!VD->isInvalidDecl() &&
|
|
||||||
VD->isThisDeclarationADefinition() == VarDecl::TentativeDefinition) {
|
|
||||||
if (const VarDecl *Def = VD->getDefinition()) {
|
|
||||||
if (Def->hasAttr<AliasAttr>()) {
|
|
||||||
Diag(VD->getLocation(), diag::err_tentative_after_alias)
|
|
||||||
<< VD->getDeclName();
|
|
||||||
Diag(Def->getLocation(), diag::note_previous_definition);
|
|
||||||
VD->setInvalidDecl();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const DeclContext *DC = VD->getDeclContext();
|
const DeclContext *DC = VD->getDeclContext();
|
||||||
// If there's a #pragma GCC visibility in scope, and this isn't a class
|
// If there's a #pragma GCC visibility in scope, and this isn't a class
|
||||||
// member, set the visibility of this variable.
|
// member, set the visibility of this variable.
|
||||||
|
|
|
@ -1492,6 +1492,20 @@ static void handleAliasAttr(Sema &S, Decl *D, const AttributeList &Attr) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Aliases should be on declarations, not definitions.
|
||||||
|
if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
|
||||||
|
if (FD->isThisDeclarationADefinition()) {
|
||||||
|
S.Diag(Attr.getLoc(), diag::err_alias_is_definition) << FD;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const auto *VD = cast<VarDecl>(D);
|
||||||
|
if (VD->isThisDeclarationADefinition() && VD->isExternallyVisible()) {
|
||||||
|
S.Diag(Attr.getLoc(), diag::err_alias_is_definition) << VD;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// FIXME: check if target symbol exists in current file
|
// FIXME: check if target symbol exists in current file
|
||||||
|
|
||||||
D->addAttr(::new (S.Context) AliasAttr(Attr.getRange(), S.Context, Str,
|
D->addAttr(::new (S.Context) AliasAttr(Attr.getRange(), S.Context, Str,
|
||||||
|
|
|
@ -79,7 +79,7 @@ void TestInt(void) __attribute__((constructor(123)));
|
||||||
// CHECK: FunctionDecl{{.*}}TestInt
|
// CHECK: FunctionDecl{{.*}}TestInt
|
||||||
// CHECK-NEXT: ConstructorAttr{{.*}} 123
|
// CHECK-NEXT: ConstructorAttr{{.*}} 123
|
||||||
|
|
||||||
int TestString __attribute__((alias("alias1")));
|
static int TestString __attribute__((alias("alias1")));
|
||||||
// CHECK: VarDecl{{.*}}TestString
|
// CHECK: VarDecl{{.*}}TestString
|
||||||
// CHECK-NEXT: AliasAttr{{.*}} "alias1"
|
// CHECK-NEXT: AliasAttr{{.*}} "alias1"
|
||||||
|
|
||||||
|
|
|
@ -23,22 +23,5 @@ void fun4(void);
|
||||||
void f5() {}
|
void f5() {}
|
||||||
void __attribute((alias("f5"))) fun5(void) {} // expected-error {{redefinition of 'fun5'}} // expected-note {{previous definition}}
|
void __attribute((alias("f5"))) fun5(void) {} // expected-error {{redefinition of 'fun5'}} // expected-note {{previous definition}}
|
||||||
|
|
||||||
int v1;
|
int var1 __attribute((alias("v1"))); // expected-error {{definition 'var1' cannot also be an alias}}
|
||||||
int var1 __attribute((alias("v1"))); // expected-note {{previous definition}}
|
static int var2 __attribute((alias("v2"))) = 2; // expected-error {{definition 'var2' cannot also be an alias}}
|
||||||
int var1 __attribute((alias("v1"))); // expected-error {{redefinition of 'var1'}}
|
|
||||||
|
|
||||||
int v2;
|
|
||||||
int var2 = 2; // expected-note {{previous definition}}
|
|
||||||
int var2 __attribute((alias("v2"))); // expected-error {{redefinition of 'var2'}}
|
|
||||||
|
|
||||||
int v3;
|
|
||||||
int var3 __attribute((alias("v3"))); // expected-note {{previous definition}}
|
|
||||||
int var3 = 2; // expected-error {{redefinition of 'var3'}}
|
|
||||||
|
|
||||||
int v4;
|
|
||||||
int var4; // expected-note {{previous definition}}
|
|
||||||
int var4 __attribute((alias("v4"))); // expected-error {{alias definition of 'var4' after tentative definition}}
|
|
||||||
|
|
||||||
int v5;
|
|
||||||
int var5 __attribute((alias("v5"))); // expected-note {{previous definition}}
|
|
||||||
int var5; // expected-error {{tentative definition of 'var5' after alias definition}}
|
|
||||||
|
|
Loading…
Reference in New Issue