Fixed linking of modules containing aliases to constant bitcasts. Existing behaviour...
authorDavid Chisnall <csdavec@swan.ac.uk>
Sat, 9 Jan 2010 16:27:31 +0000 (16:27 +0000)
committerDavid Chisnall <csdavec@swan.ac.uk>
Sat, 9 Jan 2010 16:27:31 +0000 (16:27 +0000)
Linking modules containing aliases to GEPs is still not quite right.  GEPs that are equivalent to bitcasts will be replaced by bitcasts, GEPs that are not will just break.  Aliases to GEPs that are not equivalent to bitcasts are horribly broken anyway (it might be worth adding an assert when creating the alias to prevent these being created; they just cause problems later).

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@93052 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Linker/LinkModules.cpp

index d69395cf9b2aa2b9155279eef49845efdb070e75..dcd696c70d4c219c1729cf7b52ac68258d3c963e 100644 (file)
@@ -855,9 +855,14 @@ static bool LinkAlias(Module *Dest, const Module *Src,
     } else {
       // No linking to be performed, simply create an identical version of the
       // alias over in the dest module...
-
+      Constant *Aliasee = DAliasee;
+      // Fixup aliases to bitcasts.  Note that aliases to GEPs are still broken
+      // by this, but aliases to GEPs are broken to a lot of other things, so
+      // it's less important.
+      if (SGA->getType() != DAliasee->getType())
+        Aliasee = ConstantExpr::getBitCast(DAliasee, SGA->getType());
       NewGA = new GlobalAlias(SGA->getType(), SGA->getLinkage(),
-                              SGA->getName(), DAliasee, Dest);
+                              SGA->getName(), Aliasee, Dest);
       CopyGVAttributes(NewGA, SGA);
 
       // Proceed to 'common' steps
@@ -1223,9 +1228,15 @@ static bool LinkAppendingVars(Module *M,
 static bool ResolveAliases(Module *Dest) {
   for (Module::alias_iterator I = Dest->alias_begin(), E = Dest->alias_end();
        I != E; ++I)
-    if (const GlobalValue *GV = I->resolveAliasedGlobal())
-      if (GV != I && !GV->isDeclaration())
-        I->replaceAllUsesWith(const_cast<GlobalValue*>(GV));
+    // We can't sue resolveGlobalAlias here because we need to preserve
+    // bitcasts and GEPs.
+    if (const Constant *C = I->getAliasee()) {
+      while (dyn_cast<GlobalAlias>(C))
+        C = cast<GlobalAlias>(C)->getAliasee();
+      const GlobalValue *GV = dyn_cast<GlobalValue>(C);
+      if (C != I && !(GV && GV->isDeclaration()))
+        I->replaceAllUsesWith(const_cast<Constant*>(C));
+    }
 
   return false;
 }