http://llvm.org/bugs/show_bug.cgi?id=10367

To summarise the PR, Chris said that a GlobalAlias's aliasee should
always be a GlobalValue (we shouldn't allow arbitrary Constants), and
the types of the alias and the aliasee shouldn't be required to match.

Duncan pointed out that even if the aliasee is a GlobalValue, anyone
could call ReplaceAllUsesWith() and change it into something that is
no longer a GlobalValue (but is presumably still a Constant). In my
testing I found that this is a real problem: GlobalOpt will do
someGlobalValue->replaceAllUsesWith(someBitcastExpression).

Here's an attempt to find some middle ground. The idea is to change
the API of GlobalAlias so that it looks like the aliasee is always a
GlobalValue, but in fact we tolerate operand 0 being a bitcast, which
we strip off in getAliasee(). getAliasedGlobal() disappears, because
getAliasee() always returns a GlobalValue anyway.

There should be no change to the bitcode or textual form of LLVM IR.
But I'm a bit concerned that I didn't need to make any changes to the
bitcode writer -- maybe "make check" doesn't test it very thoroughly.

I didn't understand why GlobalAlias tolerates the aliasee being a
getelementptr ConstantExpr, so I did some archaeology, found PR4066,
and added a Clang testcase to show that we do still have to handle
this. (The reason is, even if you try to create a bitcast,
ConstantFold.cpp's FoldBitCast() will sometimes return you a
getelementptr instead.)

The patch passed "make check-all". Comments?

Thanks,
Jay.
Index: llvm/trunk/include/llvm/Transforms/Utils/ValueMapper.h
===================================================================
--- llvm/trunk/include/llvm/Transforms/Utils/ValueMapper.h	(revision 136357)
+++ llvm/trunk/include/llvm/Transforms/Utils/ValueMapper.h	(working copy)
@@ -61,18 +61,23 @@
                         RemapFlags Flags = RF_None,
                         ValueMapTypeRemapper *TypeMapper = 0);
   
-  /// MapValue - provide versions that preserve type safety for MDNode and
-  /// Constants.
+  /// MapValue - provide versions that preserve type safety for MDNode,
+  /// Constant and GlobalValue.
   inline MDNode *MapValue(const MDNode *V, ValueToValueMapTy &VM,
                           RemapFlags Flags = RF_None,
                           ValueMapTypeRemapper *TypeMapper = 0) {
-    return (MDNode*)MapValue((const Value*)V, VM, Flags, TypeMapper);
+    return cast<MDNode>(MapValue((const Value*)V, VM, Flags, TypeMapper));
   }
   inline Constant *MapValue(const Constant *V, ValueToValueMapTy &VM,
                             RemapFlags Flags = RF_None,
                             ValueMapTypeRemapper *TypeMapper = 0) {
-    return (Constant*)MapValue((const Value*)V, VM, Flags, TypeMapper);
+    return cast<Constant>(MapValue((const Value*)V, VM, Flags, TypeMapper));
   }
+  inline GlobalValue *MapValue(const GlobalValue *V, ValueToValueMapTy &VM,
+                            RemapFlags Flags = RF_None,
+                            ValueMapTypeRemapper *TypeMapper = 0) {
+    return cast<GlobalValue>(MapValue((const Value*)V, VM, Flags, TypeMapper));
+  }
   
 
 } // End llvm namespace
Index: llvm/trunk/include/llvm/GlobalAlias.h
===================================================================
--- llvm/trunk/include/llvm/GlobalAlias.h	(revision 136357)
+++ llvm/trunk/include/llvm/GlobalAlias.h	(working copy)
@@ -23,7 +23,6 @@
 namespace llvm {
 
 class Module;
-class Constant;
 template<typename ValueSubClass, typename ItemParentClass>
   class SymbolTableListTraits;
 
@@ -42,10 +41,10 @@
   /// GlobalAlias ctor - If a parent module is specified, the alias is
   /// automatically inserted into the end of the specified module's alias list.
   GlobalAlias(Type *Ty, LinkageTypes Linkage, const Twine &Name = "",
-              Constant* Aliasee = 0, Module *Parent = 0);
+              GlobalValue *Aliasee = 0, Module *Parent = 0);
 
   /// Provide fast operand accessors
-  DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
+  DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Constant);
 
   /// removeFromParent - This method unlinks 'this' from the containing module,
   /// but does not delete it.
@@ -58,16 +57,13 @@
   virtual void eraseFromParent();
 
   /// set/getAliasee - These methods retrive and set alias target.
-  void setAliasee(Constant *GV);
-  const Constant *getAliasee() const {
-    return cast_or_null<Constant>(getOperand(0));
+  void setAliasee(GlobalValue *Aliasee) {
+    setOperand(0, Aliasee);
   }
-  Constant *getAliasee() {
-    return cast_or_null<Constant>(getOperand(0));
+  const GlobalValue *getAliasee() const {
+    return const_cast<GlobalAlias *>(this)->getAliasee();
   }
-  /// getAliasedGlobal() - Aliasee can be either global or bitcast of
-  /// global. This method retrives the global for both aliasee flavours.
-  const GlobalValue *getAliasedGlobal() const;
+  GlobalValue *getAliasee();
 
   /// resolveAliasedGlobal() - This method tries to ultimately resolve the alias
   /// by going through the aliasing chain and trying to find the very last
@@ -88,7 +84,7 @@
   public FixedNumOperandTraits<GlobalAlias, 1> {
 };
 
-DEFINE_TRANSPARENT_OPERAND_ACCESSORS(GlobalAlias, Value)
+DEFINE_TRANSPARENT_CASTED_OPERAND_ACCESSORS(GlobalAlias, Constant)
 
 } // End llvm namespace
 
Index: llvm/trunk/tools/llvm-nm/llvm-nm.cpp
===================================================================
--- llvm/trunk/tools/llvm-nm/llvm-nm.cpp	(revision 136357)
+++ llvm/trunk/tools/llvm-nm/llvm-nm.cpp	(working copy)
@@ -230,7 +230,7 @@
   if (isa<GlobalVariable>(GV) && GV.hasInternalLinkage())  return 'd';
   if (isa<GlobalVariable>(GV))                             return 'D';
   if (const GlobalAlias *GA = dyn_cast<GlobalAlias>(&GV)) {
-    const GlobalValue *AliasedGV = GA->getAliasedGlobal();
+    const GlobalValue *AliasedGV = GA->getAliasee();
     if (isa<Function>(AliasedGV))                          return 'T';
     if (isa<GlobalVariable>(AliasedGV))                    return 'D';
   }
Index: llvm/trunk/tools/lto/LTOModule.cpp
===================================================================
--- llvm/trunk/tools/lto/LTOModule.cpp	(revision 136357)
+++ llvm/trunk/tools/lto/LTOModule.cpp	(working copy)
@@ -657,7 +657,7 @@
 }
 
 static bool isAliasToDeclaration(const GlobalAlias &V) {
-  return isDeclaration(*V.getAliasedGlobal());
+  return isDeclaration(*V.getAliasee());
 }
 
 bool LTOModule::ParseSymbols() {
Index: llvm/trunk/lib/Linker/LinkModules.cpp
===================================================================
--- llvm/trunk/lib/Linker/LinkModules.cpp	(revision 136357)
+++ llvm/trunk/lib/Linker/LinkModules.cpp	(working copy)
@@ -826,7 +826,7 @@
 void ModuleLinker::linkAliasBodies() {
   for (Module::alias_iterator I = SrcM->alias_begin(), E = SrcM->alias_end();
        I != E; ++I)
-    if (Constant *Aliasee = I->getAliasee()) {
+    if (GlobalValue *Aliasee = I->getAliasee()) {
       GlobalAlias *DA = cast<GlobalAlias>(ValueMap[I]);
       DA->setAliasee(MapValue(Aliasee, ValueMap, RF_None, &TypeMap));
     }
Index: llvm/trunk/lib/VMCore/Verifier.cpp
===================================================================
--- llvm/trunk/lib/VMCore/Verifier.cpp	(revision 136357)
+++ llvm/trunk/lib/VMCore/Verifier.cpp	(working copy)
@@ -455,20 +455,8 @@
           "Alias should have external or external weak linkage!", &GA);
   Assert1(GA.getAliasee(),
           "Aliasee cannot be NULL!", &GA);
-  Assert1(GA.getType() == GA.getAliasee()->getType(),
-          "Alias and aliasee types should match!", &GA);
   Assert1(!GA.hasUnnamedAddr(), "Alias cannot have unnamed_addr!", &GA);
 
-  if (!isa<GlobalValue>(GA.getAliasee())) {
-    const ConstantExpr *CE = dyn_cast<ConstantExpr>(GA.getAliasee());
-    Assert1(CE && 
-            (CE->getOpcode() == Instruction::BitCast ||
-             CE->getOpcode() == Instruction::GetElementPtr) &&
-            isa<GlobalValue>(CE->getOperand(0)),
-            "Aliasee should be either GlobalValue or bitcast of GlobalValue",
-            &GA);
-  }
-
   const GlobalValue* Aliasee = GA.resolveAliasedGlobal(/*stopOnWeak*/ false);
   Assert1(Aliasee,
           "Aliasing chain should end with function or global variable", &GA);
Index: llvm/trunk/lib/VMCore/AsmWriter.cpp
===================================================================
--- llvm/trunk/lib/VMCore/AsmWriter.cpp	(revision 136357)
+++ llvm/trunk/lib/VMCore/AsmWriter.cpp	(working copy)
@@ -1375,31 +1375,16 @@
 
   PrintLinkage(GA->getLinkage(), Out);
 
-  const Constant *Aliasee = GA->getAliasee();
-
-  if (Aliasee == 0) {
+  const GlobalValue *Aliasee = GA->getAliasee();
+  if (Aliasee->getType() != GA->getType())
+    Out << "bitcast (";
+  TypePrinter.print(Aliasee->getType(), Out);
+  Out << ' ';
+  WriteAsOperandInternal(Out, Aliasee, &TypePrinter, &Machine, Aliasee->getParent());
+  if (Aliasee->getType() != GA->getType()) {
+    Out << " to ";
     TypePrinter.print(GA->getType(), Out);
-    Out << " <<NULL ALIASEE>>";
-  } else if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(Aliasee)) {
-    TypePrinter.print(GV->getType(), Out);
-    Out << ' ';
-    PrintLLVMName(Out, GV);
-  } else if (const Function *F = dyn_cast<Function>(Aliasee)) {
-    TypePrinter.print(F->getFunctionType(), Out);
-    Out << "* ";
-
-    WriteAsOperandInternal(Out, F, &TypePrinter, &Machine, F->getParent());
-  } else if (const GlobalAlias *GA = dyn_cast<GlobalAlias>(Aliasee)) {
-    TypePrinter.print(GA->getType(), Out);
-    Out << ' ';
-    PrintLLVMName(Out, GA);
-  } else {
-    const ConstantExpr *CE = cast<ConstantExpr>(Aliasee);
-    // The only valid GEP is an all zero GEP.
-    assert((CE->getOpcode() == Instruction::BitCast ||
-            CE->getOpcode() == Instruction::GetElementPtr) &&
-           "Unsupported aliasee");
-    writeOperand(CE, false);
+    Out << ')';
   }
 
   printInfoComment(*GA);
Index: llvm/trunk/lib/VMCore/Core.cpp
===================================================================
--- llvm/trunk/lib/VMCore/Core.cpp	(revision 136357)
+++ llvm/trunk/lib/VMCore/Core.cpp	(working copy)
@@ -1185,7 +1185,7 @@
 LLVMValueRef LLVMAddAlias(LLVMModuleRef M, LLVMTypeRef Ty, LLVMValueRef Aliasee,
                           const char *Name) {
   return wrap(new GlobalAlias(unwrap(Ty), GlobalValue::ExternalLinkage, Name,
-                              unwrap<Constant>(Aliasee), unwrap (M)));
+                              unwrap<GlobalValue>(Aliasee), unwrap (M)));
 }
 
 /*--.. Operations on functions .............................................--*/
Index: llvm/trunk/lib/VMCore/Globals.cpp
===================================================================
--- llvm/trunk/lib/VMCore/Globals.cpp	(revision 136357)
+++ llvm/trunk/lib/VMCore/Globals.cpp	(working copy)
@@ -187,14 +187,12 @@
 //===----------------------------------------------------------------------===//
 
 GlobalAlias::GlobalAlias(Type *Ty, LinkageTypes Link,
-                         const Twine &Name, Constant* aliasee,
+                         const Twine &Name, GlobalValue *Aliasee,
                          Module *ParentModule)
   : GlobalValue(Ty, Value::GlobalAliasVal, &Op<0>(), 1, Link, Name) {
   LeakDetector::addGarbageObject(this);
 
-  if (aliasee)
-    assert(aliasee->getType() == Ty && "Alias and aliasee types should match!");
-  Op<0>() = aliasee;
+  Op<0>() = Aliasee;
 
   if (ParentModule)
     ParentModule->getAliasList().push_back(this);
@@ -216,26 +214,19 @@
   getParent()->getAliasList().erase(this);
 }
 
-void GlobalAlias::setAliasee(Constant *Aliasee) {
-  assert((!Aliasee || Aliasee->getType() == getType()) &&
-         "Alias and aliasee types should match!");
-  
-  setOperand(0, Aliasee);
-}
+GlobalValue *GlobalAlias::getAliasee() {
+  Constant *C = getOperand(0);
 
-const GlobalValue *GlobalAlias::getAliasedGlobal() const {
-  const Constant *C = getAliasee();
-  if (C == 0) return 0;
-  
-  if (const GlobalValue *GV = dyn_cast<GlobalValue>(C))
-    return GV;
+  // Strip off any bitcast that might have been introduced by someone calling
+  // ReplaceAllUsesWith() on our operand.
+  if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C)) {
+    assert((CE->getOpcode() == Instruction::BitCast ||
+            CE->getOpcode() == Instruction::GetElementPtr) &&
+           "Unsupported aliasee");
+    C = CE->getOperand(0);
+  }
 
-  const ConstantExpr *CE = cast<ConstantExpr>(C);
-  assert((CE->getOpcode() == Instruction::BitCast || 
-          CE->getOpcode() == Instruction::GetElementPtr) &&
-         "Unsupported aliasee");
-  
-  return dyn_cast<GlobalValue>(CE->getOperand(0));
+  return cast<GlobalValue>(C);
 }
 
 const GlobalValue *GlobalAlias::resolveAliasedGlobal(bool stopOnWeak) const {
@@ -245,7 +236,7 @@
   if (stopOnWeak && mayBeOverridden())
     return this;
 
-  const GlobalValue *GV = getAliasedGlobal();
+  const GlobalValue *GV = getAliasee();
   Visited.insert(GV);
 
   // Iterate over aliasing chain, stopping on weak alias if necessary.
@@ -253,7 +244,7 @@
     if (stopOnWeak && GA->mayBeOverridden())
       break;
 
-    GV = GA->getAliasedGlobal();
+    GV = GA->getAliasee();
 
     if (!Visited.insert(GV))
       return 0;
Index: llvm/trunk/lib/AsmParser/LLParser.cpp
===================================================================
--- llvm/trunk/lib/AsmParser/LLParser.cpp	(revision 136357)
+++ llvm/trunk/lib/AsmParser/LLParser.cpp	(working copy)
@@ -583,10 +583,12 @@
     return Error(LinkageLoc, "invalid linkage type for alias");
 
   Constant *Aliasee;
+  Type *AliasTy;
   LocTy AliaseeLoc = Lex.getLoc();
   if (Lex.getKind() != lltok::kw_bitcast &&
       Lex.getKind() != lltok::kw_getelementptr) {
     if (ParseGlobalTypeAndValue(Aliasee)) return true;
+    AliasTy = Aliasee->getType();
   } else {
     // The bitcast dest type is not present, it is implied by the dest type.
     ValID ID;
@@ -594,15 +596,19 @@
     if (ID.Kind != ValID::t_Constant)
       return Error(AliaseeLoc, "invalid aliasee");
     Aliasee = ID.ConstantVal;
+    AliasTy = Aliasee->getType();
+
+    // Strip off the bitcast or getelementptr.
+    Aliasee = dyn_cast<ConstantExpr>(Aliasee)->getOperand(0);
   }
 
-  if (!Aliasee->getType()->isPointerTy())
-    return Error(AliaseeLoc, "alias must have pointer type");
+  if (!isa<GlobalValue>(Aliasee))
+    return Error(AliaseeLoc, "alias must be global value");
 
   // Okay, create the alias but do not insert it into the module yet.
-  GlobalAlias* GA = new GlobalAlias(Aliasee->getType(),
+  GlobalAlias* GA = new GlobalAlias(AliasTy,
                                     (GlobalValue::LinkageTypes)Linkage, Name,
-                                    Aliasee);
+                                    cast<GlobalValue>(Aliasee));
   GA->setVisibility((GlobalValue::VisibilityTypes)Visibility);
 
   // See if this value already exists in the symbol table.  If so, it is either
Index: llvm/trunk/lib/Transforms/Utils/CloneModule.cpp
===================================================================
--- llvm/trunk/lib/Transforms/Utils/CloneModule.cpp	(revision 136357)
+++ llvm/trunk/lib/Transforms/Utils/CloneModule.cpp	(working copy)
@@ -110,8 +110,8 @@
        I != E; ++I) {
     GlobalAlias *GA = cast<GlobalAlias>(VMap[I]);
     GA->setLinkage(I->getLinkage());
-    if (const Constant *C = I->getAliasee())
-      GA->setAliasee(MapValue(C, VMap));
+    if (const GlobalValue *GV = I->getAliasee())
+      GA->setAliasee(MapValue(GV, VMap));
   }
 
   // And named metadata....
Index: llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp
===================================================================
--- llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp	(revision 136357)
+++ llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp	(working copy)
@@ -2655,14 +2655,15 @@
     if (J->mayBeOverridden())
       continue;
 
-    Constant *Aliasee = J->getAliasee();
-    GlobalValue *Target = cast<GlobalValue>(Aliasee->stripPointerCasts());
-    Target->removeDeadConstantUsers();
-    bool hasOneUse = Target->hasOneUse() && Aliasee->hasOneUse();
+    GlobalValue *Aliasee = J->getAliasee();
+    Aliasee->removeDeadConstantUsers();
+    bool hasOneUse = Aliasee->hasOneUse();
 
     // Make all users of the alias use the aliasee instead.
     if (!J->use_empty()) {
-      J->replaceAllUsesWith(Aliasee);
+      Constant *BitcastAliasee =
+        ConstantExpr::getBitCast(Aliasee, J->getType());
+      J->replaceAllUsesWith(BitcastAliasee);
       ++NumAliasesResolved;
       Changed = true;
     }
@@ -2675,7 +2676,7 @@
       //   @a = alias ... @f
       // into:
       //   define ... @a(...)
-      if (!Target->hasLocalLinkage())
+      if (!Aliasee->hasLocalLinkage())
         continue;
 
       // Do not perform the transform if multiple aliases potentially target the
@@ -2685,9 +2686,9 @@
         continue;
 
       // Give the aliasee the name, linkage and other attributes of the alias.
-      Target->takeName(J);
-      Target->setLinkage(J->getLinkage());
-      Target->GlobalValue::copyAttributesFrom(J);
+      Aliasee->takeName(J);
+      Aliasee->setLinkage(J->getLinkage());
+      Aliasee->GlobalValue::copyAttributesFrom(J);
     }
 
     // Delete the alias.
Index: llvm/trunk/lib/Transforms/IPO/MergeFunctions.cpp
===================================================================
--- llvm/trunk/lib/Transforms/IPO/MergeFunctions.cpp	(revision 136357)
+++ llvm/trunk/lib/Transforms/IPO/MergeFunctions.cpp	(working copy)
@@ -753,9 +753,8 @@
 
 // Replace G with an alias to F and delete G.
 void MergeFunctions::writeAlias(Function *F, Function *G) {
-  Constant *BitcastF = ConstantExpr::getBitCast(F, G->getType());
   GlobalAlias *GA = new GlobalAlias(G->getType(), G->getLinkage(), "",
-                                    BitcastF, G->getParent());
+                                    F, G->getParent());
   F->setAlignment(std::max(F->getAlignment(), G->getAlignment()));
   GA->takeName(G);
   GA->setVisibility(G->getVisibility());
Index: llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
===================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp	(revision 136357)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp	(working copy)
@@ -880,7 +880,7 @@
          I != E; ++I) {
       MCSymbol *Name = Mang->getSymbol(I);
 
-      const GlobalValue *GV = cast<GlobalValue>(I->getAliasedGlobal());
+      const GlobalValue *GV = I->getAliasee();
       MCSymbol *Target = Mang->getSymbol(GV);
 
       if (I->hasExternalLinkage() || !MAI->getWeakRefDirective())
Index: llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp
===================================================================
--- llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp	(revision 136357)
+++ llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp	(working copy)
@@ -1167,10 +1167,10 @@
     if (ValID >= ValueList.size()) {
       AliasInits.push_back(AliasInitWorklist.back());
     } else {
-      if (Constant *C = dyn_cast<Constant>(ValueList[ValID]))
-        AliasInitWorklist.back().first->setAliasee(C);
+      if (GlobalValue *GV = dyn_cast<GlobalValue>(ValueList[ValID]))
+        AliasInitWorklist.back().first->setAliasee(GV);
       else
-        return Error("Alias initializer is not a constant!");
+        return Error("Alias initializer is not a global value!");
     }
     AliasInitWorklist.pop_back();
   }
Index: cfe/trunk/test/CodeGen/2009-04-25-AliasGEP.c
===================================================================
--- cfe/trunk/test/CodeGen/2009-04-25-AliasGEP.c	(revision 0)
+++ cfe/trunk/test/CodeGen/2009-04-25-AliasGEP.c	(revision 0)
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -verify -emit-llvm-only %s
+
+// Reduced testcase from PR4066.
+struct i2c_device_id {
+    };
+      static const struct i2c_device_id w83l785ts_id[] = {
+    };
+      extern const struct i2c_device_id __mod_i2c_device_table __attribute__
+((unused, alias("w83l785ts_id")));
Index: cfe/trunk/lib/CodeGen/CGCXX.cpp
===================================================================
--- cfe/trunk/lib/CodeGen/CGCXX.cpp	(revision 136357)
+++ cfe/trunk/lib/CodeGen/CGCXX.cpp	(working copy)
@@ -141,17 +141,12 @@
   llvm::PointerType *AliasType
     = getTypes().GetFunctionType(AliasDecl)->getPointerTo();
 
-  // Find the referrent.  Some aliases might require a bitcast, in
-  // which case the caller is responsible for ensuring the soundness
-  // of these semantics.
+  // Find the referrent.
   llvm::GlobalValue *Ref = cast<llvm::GlobalValue>(GetAddrOfGlobal(TargetDecl));
-  llvm::Constant *Aliasee = Ref;
-  if (Ref->getType() != AliasType)
-    Aliasee = llvm::ConstantExpr::getBitCast(Ref, AliasType);
 
   // Create the alias with no name.
   llvm::GlobalAlias *Alias = 
-    new llvm::GlobalAlias(AliasType, Linkage, "", Aliasee, &getModule());
+    new llvm::GlobalAlias(AliasType, Linkage, "", Ref, &getModule());
 
   // Switch any previous uses to the alias.
   StringRef MangledName = getMangledName(AliasDecl);
Index: cfe/trunk/lib/CodeGen/CodeGenModule.cpp
===================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.cpp	(revision 136357)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp	(working copy)
@@ -1542,19 +1542,25 @@
 
   // Create a reference to the named value.  This ensures that it is emitted
   // if a deferred decl.
+  llvm::PointerType *AliasTy = llvm::PointerType::getUnqual(DeclTy);
   llvm::Constant *Aliasee;
   if (isa<llvm::FunctionType>(DeclTy))
     Aliasee = GetOrCreateLLVMFunction(AA->getAliasee(), DeclTy, GlobalDecl(),
                                       /*ForVTable=*/false);
   else
-    Aliasee = GetOrCreateLLVMGlobal(AA->getAliasee(),
-                                    llvm::PointerType::getUnqual(DeclTy), 0);
+    Aliasee = GetOrCreateLLVMGlobal(AA->getAliasee(), AliasTy, 0);
 
+  // Strip off a bitcast if we got one back.
+  if (llvm::ConstantExpr *CE = dyn_cast<llvm::ConstantExpr>(Aliasee)) {
+    assert(CE->getOpcode() == llvm::Instruction::BitCast);
+    Aliasee = CE->getOperand(0);
+  }
+
   // Create the new alias itself, but don't set a name yet.
   llvm::GlobalValue *GA =
-    new llvm::GlobalAlias(Aliasee->getType(),
+    new llvm::GlobalAlias(AliasTy,
                           llvm::Function::ExternalLinkage,
-                          "", Aliasee, &getModule());
+                          "", cast<llvm::GlobalValue>(Aliasee), &getModule());
 
   if (Entry) {
     assert(Entry->isDeclaration());
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to