1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2025-01-31 20:51:52 +01:00

[WebAssembly] Don't error on conflicting uses of prototype-less functions

When we can't determine with certainty the signature of a function
import we pick the fist signature we find rather than error'ing out.

The resulting program might not do what is expected since we might pick
the wrong signature.  However since undefined behavior in C to use the
same function with different signatures this seems better than refusing
to compile such programs.

Fixes PR40472

Differential Revision: https://reviews.llvm.org/D58304

llvm-svn: 354523
This commit is contained in:
Sam Clegg 2019-02-20 22:40:57 +00:00
parent 117293b921
commit 351dfac732
2 changed files with 30 additions and 6 deletions

View File

@ -89,22 +89,24 @@ bool WebAssemblyAddMissingPrototypes::runOnModule(Module &M) {
Function *NewF = nullptr;
for (Use &U : F.uses()) {
LLVM_DEBUG(dbgs() << "prototype-less use: " << F.getName() << "\n");
LLVM_DEBUG(dbgs() << *U.getUser() << "\n");
if (auto *BC = dyn_cast<BitCastOperator>(U.getUser())) {
if (auto *DestType = dyn_cast<FunctionType>(
BC->getDestTy()->getPointerElementType())) {
if (!NewType) {
// Create a new function with the correct type
NewType = DestType;
LLVM_DEBUG(dbgs() << "found function type: " << *NewType << "\n");
NewF = Function::Create(NewType, F.getLinkage(), F.getName() + ".fixed_sig");
NewF->setAttributes(F.getAttributes());
NewF->removeFnAttr("no-prototype");
Replacements.emplace_back(&F, NewF);
} else {
if (NewType != DestType) {
report_fatal_error("Prototypeless function used with "
"conflicting signatures: " +
F.getName());
}
} else if (NewType != DestType) {
errs() << "warning: prototype-less function used with "
"conflicting signatures: "
<< F.getName() << "\n";
LLVM_DEBUG(dbgs() << " " << *DestType << "\n");
LLVM_DEBUG(dbgs() << " "<< *NewType << "\n");
}
}
}

View File

@ -0,0 +1,22 @@
; RUN: opt -S -wasm-add-missing-prototypes -o %t.ll %s 2>&1 | FileCheck %s -check-prefix=WARNING
; RUN: cat %t.ll | FileCheck %s
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
target triple = "wasm32-unknown-unknown"
; WARNING: warning: prototype-less function used with conflicting signatures: foo
; CHECK-LABEL: @call_with_conflicting_prototypes
; CHECK: %call1 = call i64 bitcast (i64 (i32, i32)* @foo to i64 (i32)*)(i32 42)
; CHECK: %call2 = call i64 @foo(i32 42, i32 43)
define void @call_with_conflicting_prototypes() {
%call1 = call i64 bitcast (i64 (...)* @foo to i64 (i32)*)(i32 42)
%call2 = call i64 bitcast (i64 (...)* @foo to i64 (i32, i32)*)(i32 42, i32 43)
ret void
}
; CHECK: declare extern_weak i64 @foo(i32, i32)
declare extern_weak i64 @foo(...) #1
; CHECK-NOT: attributes {{.*}} = { {{.*}}"no-prototype"{{.*}} }
attributes #1 = { "no-prototype" }