aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorMark Seaborn <mseaborn@chromium.org>2013-05-22 10:09:50 -0700
committerMark Seaborn <mseaborn@chromium.org>2013-05-22 10:09:50 -0700
commit099f6bfc79eb94351dfe006eeaea24983f8b12a4 (patch)
tree04cb8652ce345c0efddbca42b332e86a8bf2e7f4 /lib
parente7ea8c5f10b2e490fb13570fa6b97e94d7bec6cd (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.cpp52
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();