From 5ea5c61589e62a1068746ddcc52c6aa39ec0f8b0 Mon Sep 17 00:00:00 2001 From: Nick Lewycky Date: Mon, 11 Apr 2011 22:11:20 +0000 Subject: [PATCH] Just because a GlobalVariable's initializer is [N x { i32, void ()* }] doesn't mean that it has to be ConstantArray of ConstantStruct. We might have ConstantAggregateZero, at either level, so don't crash on that. Also, semi-deprecate the sentinal value. The linker isn't aware of sentinals so we end up with the two lists appended, each with their "sentinals" on them. Different parts of LLVM treated sentinals differently, so make them all just ignore the single entry and continue on with the rest of the list. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@129307 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/ELFWriter.cpp | 6 +++++- lib/ExecutionEngine/ExecutionEngine.cpp | 6 +++++- lib/Transforms/IPO/GlobalOpt.cpp | 17 ++++++++++------- 3 files changed, 20 insertions(+), 9 deletions(-) diff --git a/lib/CodeGen/ELFWriter.cpp b/lib/CodeGen/ELFWriter.cpp index 25c2e02599e..b321a15addd 100644 --- a/lib/CodeGen/ELFWriter.cpp +++ b/lib/CodeGen/ELFWriter.cpp @@ -662,12 +662,16 @@ bool ELFWriter::EmitSpecialLLVMGlobal(const GlobalVariable *GV) { void ELFWriter::EmitXXStructorList(Constant *List, ELFSection &Xtor) { // Should be an array of '{ i32, void ()* }' structs. The first value is the // init priority, which we ignore. + if (List->isNullValue()) return; ConstantArray *InitList = cast(List); for (unsigned i = 0, e = InitList->getNumOperands(); i != e; ++i) { + if (InitList->getOperand(i)->isNullValue()) + continue; ConstantStruct *CS = cast(InitList->getOperand(i)); if (CS->getOperand(1)->isNullValue()) - return; // Found a null terminator, exit printing. + continue; + // Emit the function pointer. EmitGlobalConstant(CS->getOperand(1), Xtor); } diff --git a/lib/ExecutionEngine/ExecutionEngine.cpp b/lib/ExecutionEngine/ExecutionEngine.cpp index 13e07acc151..6d767be492b 100644 --- a/lib/ExecutionEngine/ExecutionEngine.cpp +++ b/lib/ExecutionEngine/ExecutionEngine.cpp @@ -313,13 +313,17 @@ void ExecutionEngine::runStaticConstructorsDestructors(Module *module, // Should be an array of '{ i32, void ()* }' structs. The first value is // the init priority, which we ignore. + if (isa(GV->getInitializer())) + return; ConstantArray *InitList = cast(GV->getInitializer()); for (unsigned i = 0, e = InitList->getNumOperands(); i != e; ++i) { + if (isa(InitList->getOperand(i))) + continue; ConstantStruct *CS = cast(InitList->getOperand(i)); Constant *FP = CS->getOperand(1); if (FP->isNullValue()) - break; // Found a null terminator, exit. + continue; // Found a sentinal value, ignore. // Strip off constant expression casts. if (ConstantExpr *CE = dyn_cast(FP)) diff --git a/lib/Transforms/IPO/GlobalOpt.cpp b/lib/Transforms/IPO/GlobalOpt.cpp index ca4ea5c5857..ded58aca75f 100644 --- a/lib/Transforms/IPO/GlobalOpt.cpp +++ b/lib/Transforms/IPO/GlobalOpt.cpp @@ -1954,14 +1954,15 @@ GlobalVariable *GlobalOpt::FindGlobalCtors(Module &M) { // Verify that the initializer is simple enough for us to handle. We are // only allowed to optimize the initializer if it is unique. if (!GV->hasUniqueInitializer()) return 0; - - ConstantArray *CA = dyn_cast(GV->getInitializer()); - if (!CA) return 0; + + if (isa(GV->getInitializer())) + return GV; + ConstantArray *CA = cast(GV->getInitializer()); for (User::op_iterator i = CA->op_begin(), e = CA->op_end(); i != e; ++i) { - ConstantStruct *CS = dyn_cast(*i); - if (!CS) return 0; - + if (isa(*i)) + continue; + ConstantStruct *CS = cast(*i); if (isa(CS->getOperand(1))) continue; @@ -1981,6 +1982,8 @@ GlobalVariable *GlobalOpt::FindGlobalCtors(Module &M) { /// ParseGlobalCtors - Given a llvm.global_ctors list that we can understand, /// return a list of the functions and null terminator as a vector. static std::vector ParseGlobalCtors(GlobalVariable *GV) { + if (GV->getInitializer()->isNullValue()) + return std::vector(); ConstantArray *CA = cast(GV->getInitializer()); std::vector Result; Result.reserve(CA->getNumOperands()); @@ -2011,7 +2014,7 @@ static GlobalVariable *InstallGlobalCtors(GlobalVariable *GCL, const PointerType *PFTy = PointerType::getUnqual(FTy); CSVals[1] = Constant::getNullValue(PFTy); CSVals[0] = ConstantInt::get(Type::getInt32Ty(GCL->getContext()), - 2147483647); + 0x7fffffff); } CAList.push_back(ConstantStruct::get(GCL->getContext(), CSVals, false)); }