forked from OSchip/llvm-project
Fix bug: FunctionResolve/2003-10-21-GlobalTypeDifference.ll
llvm-svn: 9359
This commit is contained in:
parent
de20d44b3e
commit
af2c00bf14
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue