[tint][ir][fuzz] Gracefully handle builtin calls with null results
Fixes: 354724070
Change-Id: I72149d1e9b29ff766166a5e5ba50d4d29c290406
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/199778
Commit-Queue: Ryan Harrison <rharrison@chromium.org>
Auto-Submit: Ryan Harrison <rharrison@chromium.org>
Reviewed-by: James Price <jrprice@google.com>
Commit-Queue: James Price <jrprice@google.com>
diff --git a/src/tint/lang/core/ir/validator.cc b/src/tint/lang/core/ir/validator.cc
index cef04d5..e78cca0 100644
--- a/src/tint/lang/core/ir/validator.cc
+++ b/src/tint/lang/core/ir/validator.cc
@@ -1212,15 +1212,23 @@
symbols_,
};
- auto result = core::intrinsic::LookupFn(context, call->FriendlyName().c_str(), call->FuncId(),
- Empty, args, core::EvaluationStage::kRuntime);
- if (result != Success) {
- AddError(call) << result.Failure();
+ auto builtin = core::intrinsic::LookupFn(context, call->FriendlyName().c_str(), call->FuncId(),
+ Empty, args, core::EvaluationStage::kRuntime);
+ if (builtin != Success) {
+ AddError(call) << builtin.Failure();
return;
}
- if (result->return_type != call->Result(0)->Type()) {
+ TINT_ASSERT(builtin->return_type);
+
+ if (call->Result(0) == nullptr) {
+ AddError(call) << "call to builtin does not have a return type";
+ return;
+ }
+
+ if (builtin->return_type != call->Result(0)->Type()) {
AddError(call) << "call result type does not match builtin return type";
+ return;
}
}
diff --git a/src/tint/lang/core/ir/validator_test.cc b/src/tint/lang/core/ir/validator_test.cc
index b2aac77..32b1cc5 100644
--- a/src/tint/lang/core/ir/validator_test.cc
+++ b/src/tint/lang/core/ir/validator_test.cc
@@ -702,6 +702,72 @@
)");
}
+TEST_F(IR_ValidatorTest, CallToBuiltinMissingResult) {
+ auto* f = b.Function("f", ty.void_());
+ b.Append(f->Block(), [&] {
+ auto* c = b.Call(ty.f32(), BuiltinFn::kAbs, 1_f);
+ c->SetResults(Vector{static_cast<ir::InstructionResult*>(nullptr)});
+ b.Return(f);
+ });
+
+ auto res = ir::Validate(mod);
+ ASSERT_NE(res, Success);
+ EXPECT_EQ(res.Failure().reason.Str(),
+ R"(:3:5 error: abs: result is undefined
+ undef = abs 1.0f
+ ^^^^^
+
+:2:3 note: in block
+ $B1: {
+ ^^^
+
+:3:13 error: abs: call to builtin does not have a return type
+ undef = abs 1.0f
+ ^^^
+
+:2:3 note: in block
+ $B1: {
+ ^^^
+
+note: # Disassembly
+%f = func():void {
+ $B1: {
+ undef = abs 1.0f
+ ret
+ }
+}
+)");
+}
+
+TEST_F(IR_ValidatorTest, CallToBuiltinMismatchResultType) {
+ auto* f = b.Function("f", ty.void_());
+ b.Append(f->Block(), [&] {
+ auto* c = b.Call(ty.f32(), BuiltinFn::kAbs, 1_f);
+ c->Result(0)->SetType(ty.i32());
+ b.Return(f);
+ });
+
+ auto res = ir::Validate(mod);
+ ASSERT_NE(res, Success);
+ EXPECT_EQ(res.Failure().reason.Str(),
+ R"(:3:14 error: abs: call result type does not match builtin return type
+ %2:i32 = abs 1.0f
+ ^^^
+
+:2:3 note: in block
+ $B1: {
+ ^^^
+
+note: # Disassembly
+%f = func():void {
+ $B1: {
+ %2:i32 = abs 1.0f
+ ret
+ }
+}
+)");
+}
+
TEST_F(IR_ValidatorTest, Construct_Struct_ZeroValue) {
auto* str_ty = ty.Struct(mod.symbols.New("MyStruct"), {
{mod.symbols.New("a"), ty.i32()},