aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Seaborn <mseaborn@chromium.org>2012-10-17 19:29:37 -0700
committerMark Seaborn <mseaborn@chromium.org>2012-10-17 19:29:37 -0700
commit19bfdca1e43752e134bafb3014508f66003b8873 (patch)
tree649ab98289c1d2793a8e65fe601895d8978d397d
parentb46cdaf9e7d5c0e0b6ba3b8cc20059525b7365aa (diff)
PNaCl: Fix nacl-expand-ctors pass to handle llvm.global_ctors being zeroinitializer
This case can happen if optimisation removes initializers. BUG=http://code.google.com/p/nativeclient/issues/detail?id=3018 TEST=test/Transforms/NaCl/expand-ctors-zeroinit.ll Review URL: https://codereview.chromium.org/11190028
-rw-r--r--lib/Transforms/NaCl/ExpandCtors.cpp34
-rw-r--r--test/Transforms/NaCl/expand-ctors-zeroinit.ll16
2 files changed, 34 insertions, 16 deletions
diff --git a/lib/Transforms/NaCl/ExpandCtors.cpp b/lib/Transforms/NaCl/ExpandCtors.cpp
index 9c5f2cd2d7..6b8130e4fb 100644
--- a/lib/Transforms/NaCl/ExpandCtors.cpp
+++ b/lib/Transforms/NaCl/ExpandCtors.cpp
@@ -79,22 +79,24 @@ static void defineFuncArray(Module &M, const char *LlvmArrayName,
std::vector<Constant*> Funcs;
GlobalVariable *Array = M.getNamedGlobal(LlvmArrayName);
- if (Array && Array->hasInitializer()) {
- 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);
+ 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);
+ }
}
// No code should be referencing global_ctors/global_dtors,
// because this symbol is internal to LLVM.
diff --git a/test/Transforms/NaCl/expand-ctors-zeroinit.ll b/test/Transforms/NaCl/expand-ctors-zeroinit.ll
new file mode 100644
index 0000000000..d02741f0b5
--- /dev/null
+++ b/test/Transforms/NaCl/expand-ctors-zeroinit.ll
@@ -0,0 +1,16 @@
+; Currently we do not define __{init,fini}_array_end as named aliases.
+; RUN: opt < %s -nacl-expand-ctors -S | not grep __init_array_end
+; RUN: opt < %s -nacl-expand-ctors -S | not grep __fini_array_end
+
+; We expect this symbol to be removed:
+; RUN: opt < %s -nacl-expand-ctors -S | not grep llvm.global_ctors
+
+; RUN: opt < %s -nacl-expand-ctors -S | FileCheck %s
+
+; If llvm.global_ctors is zeroinitializer, it should be treated the
+; same as an empty array.
+
+@llvm.global_ctors = appending global [0 x { i32, void ()* }] zeroinitializer
+
+; CHECK: @__init_array_start = internal constant [0 x void ()*] zeroinitializer
+; CHECK: @__fini_array_start = internal constant [0 x void ()*] zeroinitializer