summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2003-10-21 23:17:56 +0000
committerChris Lattner <sabre@nondot.org>2003-10-21 23:17:56 +0000
commit5858e1e3f3358d53a7aeff1a7a19a862bb814df3 (patch)
tree01d980a7f799a34c854ef24c7e471e4e2ea4d85e /lib
parent4b611631bc5dad85a22aed790c59b18d7fa58a84 (diff)
downloadllvm-5858e1e3f3358d53a7aeff1a7a19a862bb814df3.tar.gz
llvm-5858e1e3f3358d53a7aeff1a7a19a862bb814df3.tar.bz2
llvm-5858e1e3f3358d53a7aeff1a7a19a862bb814df3.tar.xz
Fix bug: FunctionResolve/2003-10-21-GlobalTypeDifference.ll
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@9359 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/Transforms/IPO/FunctionResolution.cpp74
1 files changed, 19 insertions, 55 deletions
diff --git a/lib/Transforms/IPO/FunctionResolution.cpp b/lib/Transforms/IPO/FunctionResolution.cpp
index 93e1745b6d..ecabc692b4 100644
--- a/lib/Transforms/IPO/FunctionResolution.cpp
+++ b/lib/Transforms/IPO/FunctionResolution.cpp
@@ -109,29 +109,15 @@ static bool ResolveGlobalVariables(Module &M,
std::vector<GlobalValue*> &Globals,
GlobalVariable *Concrete) {
bool Changed = false;
- assert(isa<ArrayType>(Concrete->getType()->getElementType()) &&
- "Concrete version should be an array type!");
-
- // Get the type of the things that may be resolved to us...
- const ArrayType *CATy =cast<ArrayType>(Concrete->getType()->getElementType());
- const Type *AETy = CATy->getElementType();
-
Constant *CCPR = ConstantPointerRef::get(Concrete);
for (unsigned i = 0; i != Globals.size(); ++i)
if (Globals[i] != Concrete) {
- GlobalVariable *Old = cast<GlobalVariable>(Globals[i]);
- const ArrayType *OATy = cast<ArrayType>(Old->getType()->getElementType());
- if (OATy->getElementType() != AETy || OATy->getNumElements() != 0) {
- std::cerr << "WARNING: Two global variables exist with the same name "
- << "that cannot be resolved!\n";
- return false;
- }
-
- Old->replaceAllUsesWith(ConstantExpr::getCast(CCPR, Old->getType()));
+ Constant *Cast = ConstantExpr::getCast(CCPR, Globals[i]->getType());
+ Globals[i]->replaceAllUsesWith(Cast);
// Since there are no uses of Old anymore, remove it from the module.
- M.getGlobalList().erase(Old);
+ M.getGlobalList().erase(cast<GlobalVariable>(Globals[i]));
++NumGlobals;
Changed = true;
@@ -176,32 +162,15 @@ static bool ProcessGlobalsWithSameName(Module &M,
Concrete = F;
}
} else {
- // For global variables, we have to merge C definitions int A[][4] with
- // int[6][4]. A[][4] is represented as A[0][4] by the CFE.
GlobalVariable *GV = cast<GlobalVariable>(Globals[i]);
- if (!isa<ArrayType>(GV->getType()->getElementType())) {
- Concrete = 0;
- break; // Non array's cannot be compatible with other types.
- } else if (Concrete == 0) {
- Concrete = GV;
- } else {
- // Must have different types... allow merging A[0][4] w/ A[6][4] if
- // A[0][4] is external.
- const ArrayType *NAT = cast<ArrayType>(GV->getType()->getElementType());
- const ArrayType *CAT =
- cast<ArrayType>(Concrete->getType()->getElementType());
-
- if (NAT->getElementType() != CAT->getElementType()) {
- Concrete = 0; // Non-compatible types
- break;
- } else if (NAT->getNumElements() == 0 && GV->isExternal()) {
- // Concrete remains the same
- } else if (CAT->getNumElements() == 0 && Concrete->isExternal()) {
- Concrete = GV; // Concrete becomes GV
- } else {
- Concrete = 0; // Cannot merge these types...
- break;
+ if (!GV->isExternal()) {
+ if (Concrete) {
+ std::cerr << "WARNING: Two global variables with external linkage"
+ << " exist with the same name: '" << GV->getName()
+ << "'!\n";
+ return false;
}
+ Concrete = GV;
}
}
++i;
@@ -225,21 +194,15 @@ static bool ProcessGlobalsWithSameName(Module &M,
return false; // Nothing to do? Must have multiple internal definitions.
- // We should find exactly one concrete function definition, which is
- // probably the implementation. Change all of the function definitions and
- // uses to use it instead.
- //
- if (!Concrete) {
- std::cerr << "WARNING: Found global types that are not compatible:\n";
- for (unsigned i = 0; i < Globals.size(); ++i) {
- std::cerr << "\t" << Globals[i]->getType()->getDescription() << " %"
- << Globals[i]->getName() << "\n";
- }
- std::cerr << " No linkage of globals named '" << Globals[0]->getName()
- << "' performed!\n";
- return false;
+ std::cerr << "WARNING: Found global types that are not compatible:\n";
+ for (unsigned i = 0; i < Globals.size(); ++i) {
+ std::cerr << "\t" << *Globals[i]->getType() << " %"
+ << Globals[i]->getName() << "\n";
}
+ if (!Concrete)
+ Concrete = Globals[0];
+
if (isFunction)
return ResolveFunctions(M, Globals, cast<Function>(Concrete));
else
@@ -266,7 +229,8 @@ bool FunctionResolvingPass::run(Module &M) {
GlobalValue *GV = cast<GlobalValue>(PI->second);
assert(PI->first == GV->getName() &&
"Global name and symbol table do not agree!");
- Globals[PI->first].push_back(GV);
+ if (!GV->hasInternalLinkage())
+ Globals[PI->first].push_back(GV);
}
}