diff options
author | Mark Seaborn <mseaborn@chromium.org> | 2012-10-17 19:29:37 -0700 |
---|---|---|
committer | Mark Seaborn <mseaborn@chromium.org> | 2012-10-17 19:29:37 -0700 |
commit | 19bfdca1e43752e134bafb3014508f66003b8873 (patch) | |
tree | 649ab98289c1d2793a8e65fe601895d8978d397d | |
parent | b46cdaf9e7d5c0e0b6ba3b8cc20059525b7365aa (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.cpp | 34 | ||||
-rw-r--r-- | test/Transforms/NaCl/expand-ctors-zeroinit.ll | 16 |
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 |