Skip to content

Commit 099f6bf

Browse files
author
Mark Seaborn
committed
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
1 parent e7ea8c5 commit 099f6bf

File tree

2 files changed

+47
-18
lines changed

2 files changed

+47
-18
lines changed

lib/Transforms/NaCl/ExpandCtors.cpp

Lines changed: 34 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -73,31 +73,47 @@ static bool compareEntries(FuncArrayEntry Entry1, FuncArrayEntry Entry2) {
7373
return Entry1.priority < Entry2.priority;
7474
}
7575

76+
static void readFuncList(GlobalVariable *Array, std::vector<Constant*> *Funcs) {
77+
if (!Array->hasInitializer())
78+
return;
79+
Constant *Init = Array->getInitializer();
80+
ArrayType *Ty = dyn_cast<ArrayType>(Init->getType());
81+
if (!Ty) {
82+
errs() << "Initializer: " << *Array->getInitializer() << "\n";
83+
report_fatal_error("ExpandCtors: Initializer is not of array type");
84+
}
85+
if (Ty->getNumElements() == 0)
86+
return;
87+
ConstantArray *InitList = dyn_cast<ConstantArray>(Init);
88+
if (!InitList) {
89+
errs() << "Initializer: " << *Array->getInitializer() << "\n";
90+
report_fatal_error("ExpandCtors: Unexpected initializer ConstantExpr");
91+
}
92+
std::vector<FuncArrayEntry> FuncsToSort;
93+
for (unsigned Index = 0; Index < InitList->getNumOperands(); ++Index) {
94+
ConstantStruct *CS = cast<ConstantStruct>(InitList->getOperand(Index));
95+
FuncArrayEntry Entry;
96+
Entry.priority = cast<ConstantInt>(CS->getOperand(0))->getZExtValue();
97+
Entry.func = CS->getOperand(1);
98+
FuncsToSort.push_back(Entry);
99+
}
100+
101+
std::sort(FuncsToSort.begin(), FuncsToSort.end(), compareEntries);
102+
for (std::vector<FuncArrayEntry>::iterator Iter = FuncsToSort.begin();
103+
Iter != FuncsToSort.end();
104+
++Iter) {
105+
Funcs->push_back(Iter->func);
106+
}
107+
}
108+
76109
static void defineFuncArray(Module &M, const char *LlvmArrayName,
77110
const char *StartSymbol,
78111
const char *EndSymbol) {
79112
std::vector<Constant*> Funcs;
80113

81114
GlobalVariable *Array = M.getNamedGlobal(LlvmArrayName);
82115
if (Array) {
83-
if (Array->hasInitializer() && !Array->getInitializer()->isNullValue()) {
84-
ConstantArray *InitList = cast<ConstantArray>(Array->getInitializer());
85-
std::vector<FuncArrayEntry> FuncsToSort;
86-
for (unsigned Index = 0; Index < InitList->getNumOperands(); ++Index) {
87-
ConstantStruct *CS = cast<ConstantStruct>(InitList->getOperand(Index));
88-
FuncArrayEntry Entry;
89-
Entry.priority = cast<ConstantInt>(CS->getOperand(0))->getZExtValue();
90-
Entry.func = CS->getOperand(1);
91-
FuncsToSort.push_back(Entry);
92-
}
93-
94-
std::sort(FuncsToSort.begin(), FuncsToSort.end(), compareEntries);
95-
for (std::vector<FuncArrayEntry>::iterator Iter = FuncsToSort.begin();
96-
Iter != FuncsToSort.end();
97-
++Iter) {
98-
Funcs.push_back(Iter->func);
99-
}
100-
}
116+
readFuncList(Array, &Funcs);
101117
// No code should be referencing global_ctors/global_dtors,
102118
// because this symbol is internal to LLVM.
103119
Array->eraseFromParent();
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
; RUN: opt %s -nacl-expand-ctors -S | FileCheck %s -check-prefix=NO_CTORS
2+
; NO_CTORS-NOT: __init_array_end
3+
; NO_CTORS-NOT: __fini_array_end
4+
; NO_CTORS-NOT: llvm.global_ctors
5+
6+
; RUN: opt %s -nacl-expand-ctors -S | FileCheck %s
7+
8+
; Check that the pass works when the initializer is "[]", which gets
9+
; converted into "undef" by the reader.
10+
@llvm.global_ctors = appending global [0 x { i32, void ()* }] []
11+
12+
; CHECK: @__init_array_start = internal constant [0 x void ()*] zeroinitializer
13+
; CHECK: @__fini_array_start = internal constant [0 x void ()*] zeroinitializer

0 commit comments

Comments
 (0)