@@ -136,4 +136,36 @@ void alias_with_fields(bool b) {
136136 sink (a.i ); // $ MISSING: ast,ir
137137}
138138
139+ template <typename T>
140+ union U_with_two_instantiations_of_different_size {
141+ int x;
142+ T y;
143+ };
144+
145+ struct LargeStruct {
146+ int data[64 ];
147+ };
148+
149+ void test_union_with_two_instantiations_of_different_sizes () {
150+ // A union's fields is partitioned into "chunks" for field-flow in order to
151+ // improve performance (so that a write to a field of a union does not flow
152+ // to too many reads that don't happen at runtime). The partitioning is based
153+ // the size of the types in the union. So a write to a field of size k only
154+ // flows to a read of size k.
155+ // Since field-flow is based on uninstantiated types a field can have
156+ // multiple sizes if the union is instantiated with types of
157+ // different sizes. So to compute the partition we pick the maximum size.
158+ // Because of this there are `Content`s corresponding to the union
159+ // `U_with_two_instantiations_of_different_size<T>`: The one for size
160+ // `sizeof(int)`, and the one for size `sizeof(LargeStruct)` (because
161+ // `LargeStruct` is larger than `int`). So the write to `x` writes to the
162+ // `Content` for size `sizeof(int)`, and the read of `y` reads from the
163+ // `Content` for size `sizeof(LargeStruct)`.
164+ U_with_two_instantiations_of_different_size<int > u_int;
165+ U_with_two_instantiations_of_different_size<LargeStruct> u_very_large;
166+
167+ u_int.x = user_input ();
168+ sink (u_int.y ); // $ MISSING: ir
169+ }
170+
139171} // namespace Simple
0 commit comments