summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/WebAssembly/WebAssemblyFixFunctionBitcasts.cpp
diff options
context:
space:
mode:
authorDan Gohman <dan433584@gmail.com>2017-11-28 17:15:03 +0000
committerDan Gohman <dan433584@gmail.com>2017-11-28 17:15:03 +0000
commit2803bfaf001241a98608c263a824a5f5ec542511 (patch)
tree3d7c1d9c5f61f94c44f1ebb0ef158dd5de9dd8dc /llvm/lib/Target/WebAssembly/WebAssemblyFixFunctionBitcasts.cpp
parente123aba94ead1673e8672e0fdd7ef9a75d1b205c (diff)
downloadbcm5719-llvm-2803bfaf001241a98608c263a824a5f5ec542511.tar.gz
bcm5719-llvm-2803bfaf001241a98608c263a824a5f5ec542511.zip
[WebAssembly] Support bitcasted function addresses with varargs.
Generalize FixFunctionBitcasts to handle varargs functions. This in particular fixes the case where clang bitcasts away a varargs when calling a K&R-style function. This avoids interacting with tricky ABI details because it operates at the LLVM IR level before varargs ABI details are exposed. This fixes PR35385. llvm-svn: 319186
Diffstat (limited to 'llvm/lib/Target/WebAssembly/WebAssemblyFixFunctionBitcasts.cpp')
-rw-r--r--llvm/lib/Target/WebAssembly/WebAssemblyFixFunctionBitcasts.cpp11
1 files changed, 5 insertions, 6 deletions
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyFixFunctionBitcasts.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyFixFunctionBitcasts.cpp
index 19df75c7091..6473a2bfb59 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyFixFunctionBitcasts.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyFixFunctionBitcasts.cpp
@@ -107,9 +107,10 @@ static Function *CreateWrapper(Function *F, FunctionType *Ty) {
// Determine what arguments to pass.
SmallVector<Value *, 4> Args;
Function::arg_iterator AI = Wrapper->arg_begin();
+ Function::arg_iterator AE = Wrapper->arg_end();
FunctionType::param_iterator PI = F->getFunctionType()->param_begin();
FunctionType::param_iterator PE = F->getFunctionType()->param_end();
- for (; AI != Wrapper->arg_end() && PI != PE; ++AI, ++PI) {
+ for (; AI != AE && PI != PE; ++AI, ++PI) {
if (AI->getType() != *PI) {
Wrapper->eraseFromParent();
return nullptr;
@@ -118,6 +119,9 @@ static Function *CreateWrapper(Function *F, FunctionType *Ty) {
}
for (; PI != PE; ++PI)
Args.push_back(UndefValue::get(*PI));
+ if (F->isVarArg())
+ for (; AI != AE; ++AI)
+ Args.push_back(&*AI);
CallInst *Call = CallInst::Create(F, Args, "", BB);
@@ -158,11 +162,6 @@ bool FixFunctionBitcasts::runOnModule(Module &M) {
if (!Ty)
continue;
- // Wasm varargs are not ABI-compatible with non-varargs. Just ignore
- // such casts for now.
- if (Ty->isVarArg() || F->isVarArg())
- continue;
-
auto Pair = Wrappers.insert(std::make_pair(std::make_pair(F, Ty), nullptr));
if (Pair.second)
Pair.first->second = CreateWrapper(F, Ty);
OpenPOWER on IntegriCloud