Skip to content

Commit 8ac422f

Browse files
jrpriceDawn LUCI CQ
authored andcommitted
[ir] Validate terminator operands
If they are not nullptr, we need to make sure they are alive and in scope. Fixed: 420684375 Change-Id: Ie1216a1f216d385c71e844600a7555d6d04208c0 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/243994 Reviewed-by: Ryan Harrison <rharrison@chromium.org> Commit-Queue: James Price <jrprice@google.com> Commit-Queue: dan sinclair <dsinclair@chromium.org> Auto-Submit: James Price <jrprice@google.com> Reviewed-by: dan sinclair <dsinclair@chromium.org>
1 parent 46621a3 commit 8ac422f

File tree

2 files changed

+38
-7
lines changed

2 files changed

+38
-7
lines changed

src/tint/lang/core/ir/validator.cc

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1698,12 +1698,13 @@ bool Validator::CheckResults(const ir::Instruction* inst, std::optional<size_t>
16981698
bool Validator::CheckOperand(const Instruction* inst, size_t idx) {
16991699
auto* operand = inst->Operand(idx);
17001700

1701-
// var instructions are allowed to have a nullptr operands
1702-
if (inst->Is<Var>() && operand == nullptr) {
1703-
return true;
1704-
}
1705-
17061701
if (DAWN_UNLIKELY(operand == nullptr)) {
1702+
// var instructions are allowed to have a nullptr initializers.
1703+
// terminator instructions use nullptr operands to signal 'undef'.
1704+
if (inst->IsAnyOf<Terminator, Var>()) {
1705+
return true;
1706+
}
1707+
17071708
AddError(inst, idx) << "operand is undefined";
17081709
return false;
17091710
}
@@ -3462,8 +3463,10 @@ void Validator::CheckTerminator(const Terminator* b) {
34623463
return;
34633464
}
34643465

3465-
// Note, transforms create `undef` terminator arguments (this is done in MergeReturn and
3466-
// DemoteToHelper) so we can't add validation.
3466+
// Operands must be alive and in scope if they are not nullptr.
3467+
if (!CheckOperands(b)) {
3468+
return;
3469+
}
34673470

34683471
tint::Switch(
34693472
b, //

src/tint/lang/core/ir/validator_test.cc

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1208,6 +1208,34 @@ TEST_F(IR_ValidatorTest, Scoping_UseBeforeDecl) {
12081208
)")) << res.Failure();
12091209
}
12101210

1211+
TEST_F(IR_ValidatorTest, Scoping_UseAfterNestedDecl_InTerminator) {
1212+
auto* f = b.Function("my_func", ty.void_());
1213+
b.Append(f->Block(), [&] {
1214+
auto* outer = b.If(true);
1215+
outer->AddResult(b.InstructionResult<u32>());
1216+
1217+
b.Append(outer->True(), [&] {
1218+
Let* decl = nullptr;
1219+
auto* inner = b.If(true);
1220+
b.Append(inner->True(), [&] {
1221+
decl = b.Let("decl", 42_u);
1222+
b.ExitIf(inner);
1223+
});
1224+
b.ExitIf(outer, decl);
1225+
});
1226+
1227+
b.Return(f);
1228+
});
1229+
1230+
auto res = ir::Validate(mod);
1231+
ASSERT_NE(res, Success);
1232+
EXPECT_THAT(res.Failure().reason,
1233+
testing::HasSubstr(R"(:11:17 error: exit_if: %decl is not in scope
1234+
exit_if %decl # if_1
1235+
^^^^^
1236+
)")) << res.Failure();
1237+
}
1238+
12111239
TEST_F(IR_ValidatorTest, OverrideWithoutCapability) {
12121240
b.Append(mod.root_block, [&] { b.Override("a", 1_u); });
12131241

0 commit comments

Comments
 (0)