spirv-reader: prove no const decls are created for handles

Fixed: tint:265
Change-Id: If175357d8c49707fd0cb69a811e972d9f808afe4
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/47561
Auto-Submit: David Neto <dneto@google.com>
Commit-Queue: Ben Clayton <bclayton@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Ben Clayton <bclayton@google.com>
diff --git a/src/reader/spirv/parser_impl_handle_test.cc b/src/reader/spirv/parser_impl_handle_test.cc
index ea2f2b8..196def8 100644
--- a/src/reader/spirv/parser_impl_handle_test.cc
+++ b/src/reader/spirv/parser_impl_handle_test.cc
@@ -5632,6 +5632,132 @@
          "WGSL does not support querying the level of detail of an image: ",
          {}}}));
 
+TEST_F(SpvParserTest, NeverGenerateConstDeclForHandle_UseVariableDirectly) {
+  // An ad-hoc test to prove we never had the issue
+  // feared in crbug.com/tint/265.
+  // Never create a const-declaration for a pointer to
+  // a texture or sampler. Code generation always
+  // traces back to the memory object declaration.
+  const auto assembly = Preamble() + R"(
+     OpEntryPoint Fragment %100 "main"
+     OpExecutionMode %100 OriginUpperLeft
+
+     OpName %var "var"
+     OpDecorate %var_im DescriptorSet 0
+     OpDecorate %var_im Binding 0
+     OpDecorate %var_s DescriptorSet 0
+     OpDecorate %var_s Binding 1
+  %float = OpTypeFloat 32
+  %v4float = OpTypeVector %float 4
+  %v2float = OpTypeVector %float 2
+  %v2_0 = OpConstantNull %v2float
+     %im = OpTypeImage %float 2D 0 0 0 1 Unknown
+     %si = OpTypeSampledImage %im
+      %s = OpTypeSampler
+ %ptr_im = OpTypePointer UniformConstant %im
+  %ptr_s = OpTypePointer UniformConstant %s
+ %var_im = OpVariable %ptr_im UniformConstant
+  %var_s = OpVariable %ptr_s UniformConstant
+   %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %ptr_v4 = OpTypePointer Function %v4float
+
+    %100 = OpFunction %void None %voidfn
+  %entry = OpLabel
+    %var = OpVariable %ptr_v4 Function
+
+; Try to induce generating a const-declaration of a pointer to
+; a sampler or texture.
+
+ %var_im_copy = OpCopyObject %ptr_im %var_im
+  %var_s_copy = OpCopyObject %ptr_s %var_s
+
+         %im0 = OpLoad %im %var_im_copy
+          %s0 = OpLoad %s %var_s_copy
+         %si0 = OpSampledImage %si %im0 %s0
+          %t0 = OpImageSampleImplicitLod %v4float %si0 %v2_0
+
+
+         %im1 = OpLoad %im %var_im_copy
+          %s1 = OpLoad %s %var_s_copy
+         %si1 = OpSampledImage %si %im1 %s1
+          %t1 = OpImageSampleImplicitLod %v4float %si1 %v2_0
+
+         %sum = OpFAdd %v4float %t0 %t1
+           OpStore %var %sum
+
+           OpReturn
+           OpFunctionEnd
+  )";
+  auto p = parser(test::Assemble(assembly));
+  std::cout << assembly << std::endl;
+  EXPECT_TRUE(p->BuildAndParseInternalModule()) << assembly;
+  FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
+  EXPECT_TRUE(fe.EmitBody()) << p->error();
+  EXPECT_TRUE(p->error().empty()) << p->error();
+  const auto got = ToString(p->builder(), fe.ast_body());
+  auto* expect = R"(VariableDeclStatement{
+  Variable{
+    var_1
+    function
+    __vec_4__f32
+  }
+}
+VariableDeclStatement{
+  VariableConst{
+    x_22
+    none
+    __vec_4__f32
+    {
+      Call[not set]{
+        Identifier[not set]{textureSample}
+        (
+          Identifier[not set]{x_2}
+          Identifier[not set]{x_3}
+          TypeConstructor[not set]{
+            __vec_2__f32
+            ScalarConstructor[not set]{0.000000}
+            ScalarConstructor[not set]{0.000000}
+          }
+        )
+      }
+    }
+  }
+}
+VariableDeclStatement{
+  VariableConst{
+    x_26
+    none
+    __vec_4__f32
+    {
+      Call[not set]{
+        Identifier[not set]{textureSample}
+        (
+          Identifier[not set]{x_2}
+          Identifier[not set]{x_3}
+          TypeConstructor[not set]{
+            __vec_2__f32
+            ScalarConstructor[not set]{0.000000}
+            ScalarConstructor[not set]{0.000000}
+          }
+        )
+      }
+    }
+  }
+}
+Assignment{
+  Identifier[not set]{var_1}
+  Binary[not set]{
+    Identifier[not set]{x_22}
+    add
+    Identifier[not set]{x_26}
+  }
+}
+Return{}
+)";
+  ASSERT_EQ(expect, got) << got;
+}
+
 }  // namespace
 }  // namespace spirv
 }  // namespace reader