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
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 9aa1d9c..da59fb5 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -2219,18 +2219,8 @@
     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 @@
     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 @@
     }
   }
 
-  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.