[spirv-writer] Fix missing symbol clone in entry point IO transform

Fixed: tint:701
Change-Id: Id85e1170c85eedb9f04e5759aff84edc0d1c1453
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/46900
Reviewed-by: Ben Clayton <bclayton@google.com>
Commit-Queue: James Price <jrprice@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
diff --git a/src/transform/spirv.cc b/src/transform/spirv.cc
index bbbff3f..c9da68b 100644
--- a/src/transform/spirv.cc
+++ b/src/transform/spirv.cc
@@ -324,7 +324,7 @@
   // Recurse into struct members.
   auto* struct_ty = ty->UnwrapAliasIfNeeded()->As<type::Struct>();
   for (auto* member : struct_ty->impl()->members()) {
-    member_accesses.push_back(member->symbol());
+    member_accesses.push_back(ctx.Clone(member->symbol()));
     HoistToOutputVariables(ctx, func, member->type(), member->decorations(),
                            member_accesses, store_value, stores);
     member_accesses.pop_back();
diff --git a/src/transform/spirv_test.cc b/src/transform/spirv_test.cc
index 7e44dee..efec401 100644
--- a/src/transform/spirv_test.cc
+++ b/src/transform/spirv_test.cc
@@ -442,6 +442,47 @@
   EXPECT_EQ(expect, str(got));
 }
 
+TEST_F(SpirvTest, HandleEntryPointIOTypes_WithPrivateGlobalVariable) {
+  // Test with a global variable to ensure that symbols are cloned correctly.
+  // crbug.com/tint/701
+  auto* src = R"(
+var<private> x : f32;
+
+struct VertexOutput {
+  [[builtin(position)]] Position : vec4<f32>;
+};
+
+[[stage(vertex)]]
+fn main() -> VertexOutput {
+    return VertexOutput(vec4<f32>());
+}
+)";
+
+  auto* expect = R"(
+var<private> x : f32;
+
+struct VertexOutput {
+  Position : vec4<f32>;
+};
+
+[[builtin(position)]] var<out> tint_symbol_4 : vec4<f32>;
+
+fn tint_symbol_5(tint_symbol_3 : VertexOutput) -> void {
+  tint_symbol_4 = tint_symbol_3.Position;
+}
+
+[[stage(vertex)]]
+fn main() -> void {
+  tint_symbol_5(VertexOutput(vec4<f32>()));
+  return;
+}
+)";
+
+  auto got = Run<Spirv>(src);
+
+  EXPECT_EQ(expect, str(got));
+}
+
 TEST_F(SpirvTest, HandleSampleMaskBuiltins_Basic) {
   auto* src = R"(
 [[builtin(sample_index)]] var<in> sample_index : u32;