diff options
| author | David Majnemer <david.majnemer@gmail.com> | 2015-01-19 09:00:28 +0000 |
|---|---|---|
| committer | David Majnemer <david.majnemer@gmail.com> | 2015-01-19 09:00:28 +0000 |
| commit | 2dc8146643856d29c33880b86506141d30d5866f (patch) | |
| tree | 6480c97086c09f0160678b9284effd8ea01c864c /clang/lib | |
| parent | 0540f4141fb187d6f5cb2d871bd5fbc27e1f4512 (diff) | |
| download | bcm5719-llvm-2dc8146643856d29c33880b86506141d30d5866f.tar.gz bcm5719-llvm-2dc8146643856d29c33880b86506141d30d5866f.zip | |
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
Diffstat (limited to 'clang/lib')
| -rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 38 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaDeclAttr.cpp | 14 |
2 files changed, 28 insertions, 24 deletions
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 9aa1d9ca83c..da59fb57732 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -2219,18 +2219,8 @@ static void checkNewAttributesAfterDef(Sema &S, Decl *New, const Decl *Old) { const Attr *NewAttribute = NewAttributes[I]; if (isa<AliasAttr>(NewAttribute)) { - if (FunctionDecl *FD = dyn_cast<FunctionDecl>(New)) - 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(); - } + FunctionDecl *FD = cast<FunctionDecl>(New); + S.CheckForFunctionRedefinition(FD, cast<FunctionDecl>(Def)); ++I; continue; } @@ -5103,6 +5093,18 @@ static void checkAttributesAfterMerging(Sema &S, NamedDecl &ND) { if (ND.isExternallyVisible()) { S.Diag(Attr->getLocation(), diag::err_attribute_weakref_not_static); 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(); // If there's a #pragma GCC visibility in scope, and this isn't a class // member, set the visibility of this variable. diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index 17a849ea7af..8837bbdb2bc 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -1492,6 +1492,20 @@ static void handleAliasAttr(Sema &S, Decl *D, const AttributeList &Attr) { 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 D->addAttr(::new (S.Context) AliasAttr(Attr.getRange(), S.Context, Str, |

