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 <noreply+kokoro@google.com>
Reviewed-by: Dan Sinclair <dsinclair@chromium.org>
diff --git a/src/tint/reader/spirv/function.cc b/src/tint/reader/spirv/function.cc
index a71aa42..fc465fb 100644
--- a/src/tint/reader/spirv/function.cc
+++ b/src/tint/reader/spirv/function.cc
@@ -3966,7 +3966,11 @@
     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 4f78802..600e570 100644
--- a/src/tint/reader/spirv/parser_impl.cc
+++ b/src/tint/reader/spirv/parser_impl.cc
@@ -1183,7 +1183,7 @@
                         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 @@
                                        ast::IntLiteralExpression::Suffix::kU)};
         },
         [&](const F32*) {
-            return TypedExpression{ty_.F32(),
-                                   create<ast::FloatLiteralExpression>(
-                                       source, static_cast<double>(spirv_const->GetFloat()),
-                                       ast::FloatLiteralExpression::Suffix::kF)};
+            if (auto f = CheckedConvert<f32>(AFloat(spirv_const->GetFloat()))) {
+                return TypedExpression{ty_.F32(),
+                                       create<ast::FloatLiteralExpression>(
+                                           source, static_cast<double>(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 42c0098..908d369 100644
--- a/src/tint/reader/spirv/parser_impl_test.cc
+++ b/src/tint/reader/spirv/parser_impl_test.cc
@@ -217,5 +217,35 @@
     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