From aff1656a762cb303715a3be72e58911df5c6a0f4 Mon Sep 17 00:00:00 2001 From: Antonio Maiorano Date: Fri, 18 Nov 2022 05:45:17 +0000 Subject: [PATCH] tint/spriv-reader: emit error on non-finite literal Bug: tint:1581 Bug: tint:1747 Change-Id: I2855c8e277e74ecf1465b81c4545b99fef2a321b Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/110701 Kokoro: Kokoro Reviewed-by: Dan Sinclair --- src/tint/reader/spirv/function.cc | 6 ++++- src/tint/reader/spirv/parser_impl.cc | 15 ++++++++---- src/tint/reader/spirv/parser_impl_test.cc | 30 +++++++++++++++++++++++ 3 files changed, 45 insertions(+), 6 deletions(-) diff --git a/src/tint/reader/spirv/function.cc b/src/tint/reader/spirv/function.cc index a71aa42a66..fc465fb4c5 100644 --- a/src/tint/reader/spirv/function.cc +++ b/src/tint/reader/spirv/function.cc @@ -3966,7 +3966,11 @@ TypedExpression FunctionEmitter::MaybeEmitCombinatorialValue( if (op == spv::Op::OpCompositeConstruct) { ExpressionList operands; for (uint32_t iarg = 0; iarg < inst.NumInOperands(); ++iarg) { - operands.Push(MakeOperand(inst, iarg).expr); + auto operand = MakeOperand(inst, iarg); + if (!operand) { + return {}; + } + operands.Push(operand.expr); } return {ast_type, builder_.Construct(Source{}, ast_type->Build(builder_), std::move(operands))}; diff --git a/src/tint/reader/spirv/parser_impl.cc b/src/tint/reader/spirv/parser_impl.cc index 4f78802107..600e570b55 100644 --- a/src/tint/reader/spirv/parser_impl.cc +++ b/src/tint/reader/spirv/parser_impl.cc @@ -1183,7 +1183,7 @@ const Type* ParserImpl::ConvertType(uint32_t type_id, break; case spv::BuiltIn::ClipDistance: // not supported in WGSL case spv::BuiltIn::CullDistance: // not supported in WGSL - create_ast_member = false; // Not part of the WGSL structure. + create_ast_member = false; // Not part of the WGSL structure. break; default: Fail() << "unrecognized builtin " << decoration[1]; @@ -2025,10 +2025,15 @@ TypedExpression ParserImpl::MakeConstantExpressionForScalarSpirvConstant( ast::IntLiteralExpression::Suffix::kU)}; }, [&](const F32*) { - return TypedExpression{ty_.F32(), - create( - source, static_cast(spirv_const->GetFloat()), - ast::FloatLiteralExpression::Suffix::kF)}; + if (auto f = CheckedConvert(AFloat(spirv_const->GetFloat()))) { + return TypedExpression{ty_.F32(), + create( + source, static_cast(spirv_const->GetFloat()), + ast::FloatLiteralExpression::Suffix::kF)}; + } else { + Fail() << "value cannot be represented as 'f32': " << spirv_const->GetFloat(); + return TypedExpression{}; + } }, [&](const Bool*) { const bool value = diff --git a/src/tint/reader/spirv/parser_impl_test.cc b/src/tint/reader/spirv/parser_impl_test.cc index 42c0098ad0..908d36956a 100644 --- a/src/tint/reader/spirv/parser_impl_test.cc +++ b/src/tint/reader/spirv/parser_impl_test.cc @@ -217,5 +217,35 @@ TEST_F(SpvParserTest, Impl_IsValidIdentifier) { EXPECT_TRUE(ParserImpl::IsValidIdentifier("x_")); // has underscore } +TEST_F(SpvParserTest, Impl_FailOnNonFiniteLiteral) { + auto spv = test::Assemble(R"( + OpCapability Shader + OpMemoryModel Logical GLSL450 + OpEntryPoint Fragment %main "main" %out_var_SV_TARGET + OpExecutionMode %main OriginUpperLeft + OpSource HLSL 600 + OpName %out_var_SV_TARGET "out.var.SV_TARGET" + OpName %main "main" + OpDecorate %out_var_SV_TARGET Location 0 + %float = OpTypeFloat 32 + %float_0x1p_128 = OpConstant %float -0x1p+128 + %v4float = OpTypeVector %float 4 +%_ptr_Output_v4float = OpTypePointer Output %v4float + %void = OpTypeVoid + %9 = OpTypeFunction %void + %out_var_SV_TARGET = OpVariable %_ptr_Output_v4float Output + %main = OpFunction %void None %9 + %10 = OpLabel + %12 = OpCompositeConstruct %v4float %float_0x1p_128 %float_0x1p_128 %float_0x1p_128 %float_0x1p_128 + OpStore %out_var_SV_TARGET %12 + OpReturn + OpFunctionEnd + +)"); + auto p = parser(spv); + EXPECT_FALSE(p->Parse()); + EXPECT_THAT(p->error(), HasSubstr("value cannot be represented as 'f32': -inf")); +} + } // namespace } // namespace tint::reader::spirv