From b7c2aed189b5006628a6998d3d9aca783c89c864 Mon Sep 17 00:00:00 2001 From: James Price Date: Tue, 28 Feb 2023 19:28:50 +0000 Subject: [PATCH] tint: Skip short-circuited array init const eval Otherwise we will dereference the nullptr constant::Value constructor arguments. Bug: chromium:1420256 Change-Id: I5cace9c7c4bab7815f319793fdd88be294cd0ceb Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/122101 Reviewed-by: Ben Clayton Kokoro: Kokoro Commit-Queue: James Price --- .../resolver/const_eval_binary_op_test.cc | 36 +++++++++++++++++++ src/tint/resolver/resolver.cc | 3 ++ 2 files changed, 39 insertions(+) diff --git a/src/tint/resolver/const_eval_binary_op_test.cc b/src/tint/resolver/const_eval_binary_op_test.cc index 0ddbeeb99d..ff50a24938 100644 --- a/src/tint/resolver/const_eval_binary_op_test.cc +++ b/src/tint/resolver/const_eval_binary_op_test.cc @@ -2008,6 +2008,42 @@ TEST_F(ResolverConstEvalTest, ShortCircuit_Or_Error_StructInit) { "expected 'f32', found 'bool'"); } +TEST_F(ResolverConstEvalTest, ShortCircuit_And_Error_ArrayInit) { + // const one = 1; + // const result = (one == 0) && array(4) == 0; + GlobalConst("one", Expr(1_a)); + auto* lhs = Equal("one", 0_a); + auto* rhs = Equal(Call("array", Expr(4_a)), 0_a); + GlobalConst("result", LogicalAnd(lhs, rhs)); + + EXPECT_FALSE(r()->Resolve()); + EXPECT_EQ(r()->error(), + R"(error: no matching overload for operator == (array, abstract-int) + +2 candidate operators: + operator == (T, T) -> bool where: T is abstract-int, abstract-float, f32, f16, i32, u32 or bool + operator == (vecN, vecN) -> vecN where: T is abstract-int, abstract-float, f32, f16, i32, u32 or bool +)"); +} + +TEST_F(ResolverConstEvalTest, ShortCircuit_Or_Error_ArrayInit) { + // const one = 1; + // const result = (one == 1) || array(4) == 0; + GlobalConst("one", Expr(1_a)); + auto* lhs = Equal("one", 1_a); + auto* rhs = Equal(Call("array", Expr(4_a)), 0_a); + GlobalConst("result", LogicalOr(lhs, rhs)); + + EXPECT_FALSE(r()->Resolve()); + EXPECT_EQ(r()->error(), + R"(error: no matching overload for operator == (array, abstract-int) + +2 candidate operators: + operator == (T, T) -> bool where: T is abstract-int, abstract-float, f32, f16, i32, u32 or bool + operator == (vecN, vecN) -> vecN where: T is abstract-int, abstract-float, f32, f16, i32, u32 or bool +)"); +} + //////////////////////////////////////////////// // Short-Circuit Builtin Call //////////////////////////////////////////////// diff --git a/src/tint/resolver/resolver.cc b/src/tint/resolver/resolver.cc index 6b116d9a16..cd426f73c8 100644 --- a/src/tint/resolver/resolver.cc +++ b/src/tint/resolver/resolver.cc @@ -2012,6 +2012,9 @@ sem::Call* Resolver::Call(const ast::CallExpression* expr) { auto stage = args_stage; // The evaluation stage of the call const constant::Value* value = nullptr; // The constant value for the call + if (stage == sem::EvaluationStage::kConstant && skip_const_eval_.Contains(expr)) { + stage = sem::EvaluationStage::kNotEvaluated; + } if (stage == sem::EvaluationStage::kConstant) { auto els = utils::Transform(args, [&](auto* arg) { return arg->ConstantValue(); }); if (auto r = const_eval_.ArrayOrStructCtor(ty, std::move(els))) {