Index: lib/Target/WebAssembly/WebAssemblyAddMissingPrototypes.cpp =================================================================== --- lib/Target/WebAssembly/WebAssemblyAddMissingPrototypes.cpp +++ lib/Target/WebAssembly/WebAssemblyAddMissingPrototypes.cpp @@ -78,10 +78,13 @@ report_fatal_error( "Functions with 'no-prototype' attribute must take varargs: " + F.getName()); - if (F.getFunctionType()->getNumParams() != 0) - report_fatal_error( - "Functions with 'no-prototype' attribute should not have params: " + - F.getName()); + if (F.getFunctionType()->getNumParams() != 0) { + for (Argument &A : F.args()) + if (!A.hasStructRetAttr()) + report_fatal_error("Functions with 'no-prototype' attribute should " + "not have params: " + + F.getName()); + } // Create a function prototype based on the first call site (first bitcast) // that we find. Index: test/CodeGen/WebAssembly/add-prototypes.ll =================================================================== --- test/CodeGen/WebAssembly/add-prototypes.ll +++ test/CodeGen/WebAssembly/add-prototypes.ll @@ -56,6 +56,17 @@ ret void } +; Check if a sret parameter works in a no-prototype function. +; CHECK-LABEL: @sret_param +; CHECK: call void @make_struct_foo(%struct.foo* sret %foo) +%struct.foo = type { i32, i32 } +declare void @make_struct_foo(%struct.foo* sret, ...) #1 +define void @sret_param() { + %foo = alloca %struct.foo, align 4 + call void bitcast (void (%struct.foo*, ...)* @make_struct_foo to void (%struct.foo*)*)(%struct.foo* sret %foo) + ret void +} + declare void @func_param(i64 (...)*) ; CHECK: declare void @func_not_called()