diff options
author | Mark Seaborn <mseaborn@chromium.org> | 2013-05-22 10:09:50 -0700 |
---|---|---|
committer | Mark Seaborn <mseaborn@chromium.org> | 2013-05-22 10:09:50 -0700 |
commit | 099f6bfc79eb94351dfe006eeaea24983f8b12a4 (patch) | |
tree | 04cb8652ce345c0efddbca42b332e86a8bf2e7f4 /lib | |
parent | e7ea8c5f10b2e490fb13570fa6b97e94d7bec6cd (diff) |
PNaCl: Fix ExpandCtors to handle an empty list case
While writing a test, I noticed that ExpandCtors crashes if given the
empty list "[]", because this gets converted into an UndefValue
ConstantExpr by the LLVM assembly reader.
Fix this by checking the array's size via its type. This replaces the
isNullValue() check.
Make error handling cleaner by splitting out a separate function.
BUG=none
TEST=test/Transforms/NaCl/expand-ctors-emptylist.ll
Review URL: https://codereview.chromium.org/15659005
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Transforms/NaCl/ExpandCtors.cpp | 52 |
1 files changed, 34 insertions, 18 deletions
diff --git a/lib/Transforms/NaCl/ExpandCtors.cpp b/lib/Transforms/NaCl/ExpandCtors.cpp index 30d56fee6b..fd38e2f0f1 100644 --- a/lib/Transforms/NaCl/ExpandCtors.cpp +++ b/lib/Transforms/NaCl/ExpandCtors.cpp @@ -73,6 +73,39 @@ static bool compareEntries(FuncArrayEntry Entry1, FuncArrayEntry Entry2) { return Entry1.priority < Entry2.priority; } +static void readFuncList(GlobalVariable *Array, std::vector<Constant*> *Funcs) { + if (!Array->hasInitializer()) + return; + Constant *Init = Array->getInitializer(); + ArrayType *Ty = dyn_cast<ArrayType>(Init->getType()); + if (!Ty) { + errs() << "Initializer: " << *Array->getInitializer() << "\n"; + report_fatal_error("ExpandCtors: Initializer is not of array type"); + } + if (Ty->getNumElements() == 0) + return; + ConstantArray *InitList = dyn_cast<ConstantArray>(Init); + if (!InitList) { + errs() << "Initializer: " << *Array->getInitializer() << "\n"; + report_fatal_error("ExpandCtors: Unexpected initializer ConstantExpr"); + } + std::vector<FuncArrayEntry> FuncsToSort; + for (unsigned Index = 0; Index < InitList->getNumOperands(); ++Index) { + ConstantStruct *CS = cast<ConstantStruct>(InitList->getOperand(Index)); + FuncArrayEntry Entry; + Entry.priority = cast<ConstantInt>(CS->getOperand(0))->getZExtValue(); + Entry.func = CS->getOperand(1); + FuncsToSort.push_back(Entry); + } + + std::sort(FuncsToSort.begin(), FuncsToSort.end(), compareEntries); + for (std::vector<FuncArrayEntry>::iterator Iter = FuncsToSort.begin(); + Iter != FuncsToSort.end(); + ++Iter) { + Funcs->push_back(Iter->func); + } +} + static void defineFuncArray(Module &M, const char *LlvmArrayName, const char *StartSymbol, const char *EndSymbol) { @@ -80,24 +113,7 @@ static void defineFuncArray(Module &M, const char *LlvmArrayName, GlobalVariable *Array = M.getNamedGlobal(LlvmArrayName); if (Array) { - if (Array->hasInitializer() && !Array->getInitializer()->isNullValue()) { - ConstantArray *InitList = cast<ConstantArray>(Array->getInitializer()); - std::vector<FuncArrayEntry> FuncsToSort; - for (unsigned Index = 0; Index < InitList->getNumOperands(); ++Index) { - ConstantStruct *CS = cast<ConstantStruct>(InitList->getOperand(Index)); - FuncArrayEntry Entry; - Entry.priority = cast<ConstantInt>(CS->getOperand(0))->getZExtValue(); - Entry.func = CS->getOperand(1); - FuncsToSort.push_back(Entry); - } - - std::sort(FuncsToSort.begin(), FuncsToSort.end(), compareEntries); - for (std::vector<FuncArrayEntry>::iterator Iter = FuncsToSort.begin(); - Iter != FuncsToSort.end(); - ++Iter) { - Funcs.push_back(Iter->func); - } - } + readFuncList(Array, &Funcs); // No code should be referencing global_ctors/global_dtors, // because this symbol is internal to LLVM. Array->eraseFromParent(); |