diff options
author | Dan Gohman <dan433584@gmail.com> | 2017-11-28 17:15:03 +0000 |
---|---|---|
committer | Dan Gohman <dan433584@gmail.com> | 2017-11-28 17:15:03 +0000 |
commit | 2803bfaf001241a98608c263a824a5f5ec542511 (patch) | |
tree | 3d7c1d9c5f61f94c44f1ebb0ef158dd5de9dd8dc /llvm/lib/Target/WebAssembly/WebAssemblyFixFunctionBitcasts.cpp | |
parent | e123aba94ead1673e8672e0fdd7ef9a75d1b205c (diff) | |
download | bcm5719-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.cpp | 11 |
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); |