validation: Fix continue-bypasses-decl check
An expression that is inside an if-statement condition does not have a "current block", which is what we were using to see if the usage was inside a continuing block. Use the current statement to find the containing block instead. Fixed: chromium:1251664 Change-Id: Icc808ca1cf6a1b51757da8303901fa5ecb693e83 Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/65520 Kokoro: Kokoro <noreply+kokoro@google.com> Reviewed-by: Ben Clayton <bclayton@google.com>
This commit is contained in:
parent
1ca6fbad8f
commit
7166f6ba93
|
@ -2971,12 +2971,12 @@ bool Resolver::Identifier(ast::IdentifierExpression* expr) {
|
|||
var->users.push_back(expr);
|
||||
set_referenced_from_function_if_needed(var, true);
|
||||
|
||||
if (current_block_) {
|
||||
if (current_statement_) {
|
||||
// If identifier is part of a loop continuing block, make sure it
|
||||
// doesn't refer to a variable that is bypassed by a continue statement
|
||||
// in the loop's body block.
|
||||
if (auto* continuing_block =
|
||||
current_block_
|
||||
current_statement_
|
||||
->FindFirstParent<sem::LoopContinuingBlockStatement>()) {
|
||||
auto* loop_block =
|
||||
continuing_block->FindFirstParent<sem::LoopBlockStatement>();
|
||||
|
|
|
@ -615,6 +615,36 @@ TEST_F(
|
|||
"continuing block");
|
||||
}
|
||||
|
||||
TEST_F(ResolverValidationTest,
|
||||
Stmt_Loop_ContinueInLoopBodySubscopeBeforeDecl_UsageOutsideBlock) {
|
||||
// loop {
|
||||
// if (true) {
|
||||
// continue; // bypasses z decl (if we reach here)
|
||||
// }
|
||||
// var z : i32;
|
||||
// continuing {
|
||||
// // Must fail even if z is used in an expression that isn't
|
||||
// // directly contained inside a block.
|
||||
// if (z < 2) {
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
auto error_loc = Source{Source::Location{12, 34}};
|
||||
auto* body = Block(If(Expr(true), Block(create<ast::ContinueStatement>())),
|
||||
Decl(Var("z", ty.i32(), ast::StorageClass::kNone)));
|
||||
auto* compare = create<ast::BinaryExpression>(ast::BinaryOp::kLessThan,
|
||||
Expr(error_loc, "z"), Expr(2));
|
||||
auto* continuing = Block(If(compare, Block()));
|
||||
auto* loop_stmt = Loop(body, continuing);
|
||||
WrapInFunction(loop_stmt);
|
||||
|
||||
EXPECT_FALSE(r()->Resolve()) << r()->error();
|
||||
EXPECT_EQ(r()->error(),
|
||||
"12:34 error: continue statement bypasses declaration of 'z' in "
|
||||
"continuing block");
|
||||
}
|
||||
|
||||
TEST_F(ResolverValidationTest,
|
||||
Stmt_Loop_ContinueInLoopBodySubscopeBeforeDecl_UsageInContinuingLoop) {
|
||||
// loop {
|
||||
|
|
Loading…
Reference in New Issue