[ir][validator] Fix return value check for void functions.
If a function returns `void` the `CheckReturn` in the IR validator was
just checking if the return `Value` was true. In the case where the
return has a value of `undef` then that check would not trigger as
`nullptr` is false.
Add a `HasValue` into the `ir::Return` so we can determine if anything
exists in the operands, instead of checking the truthyness of the value
itself.
Bug: 422810448
Change-Id: I9d0c72632144289fd05c2aecef82972ade757066
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/246154
Reviewed-by: Ryan Harrison <rharrison@chromium.org>
Commit-Queue: dan sinclair <dsinclair@chromium.org>
Auto-Submit: dan sinclair <dsinclair@chromium.org>
Commit-Queue: Ryan Harrison <rharrison@chromium.org>
diff --git a/src/tint/lang/core/ir/return.h b/src/tint/lang/core/ir/return.h
index 6ebff1c..574dccf 100644
--- a/src/tint/lang/core/ir/return.h
+++ b/src/tint/lang/core/ir/return.h
@@ -81,10 +81,11 @@
/// @returns the function being returned
const Function* Func() const;
+ /// @returns true if the return has a value set
+ bool HasValue() const { return operands_.Length() > kArgsOperandOffset; }
+
/// @returns the return value, or nullptr
- ir::Value* Value() const {
- return operands_.Length() > kArgsOperandOffset ? operands_[kArgsOperandOffset] : nullptr;
- }
+ ir::Value* Value() const { return HasValue() ? operands_[kArgsOperandOffset] : nullptr; }
/// Sets the return value
/// @param val the new return value
diff --git a/src/tint/lang/core/ir/validator.cc b/src/tint/lang/core/ir/validator.cc
index b6998df..2b49e18 100644
--- a/src/tint/lang/core/ir/validator.cc
+++ b/src/tint/lang/core/ir/validator.cc
@@ -3626,7 +3626,7 @@
}
if (func->ReturnType()->Is<core::type::Void>()) {
- if (ret->Value()) {
+ if (ret->HasValue()) {
AddError(ret) << "unexpected return value";
}
} else {
diff --git a/src/tint/lang/core/ir/validator_flow_control_test.cc b/src/tint/lang/core/ir/validator_flow_control_test.cc
index 125686b..8ab90e5 100644
--- a/src/tint/lang/core/ir/validator_flow_control_test.cc
+++ b/src/tint/lang/core/ir/validator_flow_control_test.cc
@@ -1868,6 +1868,21 @@
)")) << res.Failure();
}
+TEST_F(IR_ValidatorTest, Return_UnexpectedValue_NullValue_WithVoid) {
+ auto* f = b.Function("my_func", ty.void_());
+ b.Append(f->Block(), [&] { //
+ b.Return(f, nullptr);
+ });
+
+ auto res = ir::Validate(mod);
+ ASSERT_NE(res, Success);
+ EXPECT_THAT(res.Failure().reason,
+ testing::HasSubstr(R"(:3:5 error: return: unexpected return value
+ ret undef
+ ^^^^^^^^^
+)")) << res.Failure();
+}
+
TEST_F(IR_ValidatorTest, Return_MissingValue) {
auto* f = b.Function("my_func", ty.i32());
b.Append(f->Block(), [&] { //