1 // { dg-do run { target c++11 } }
4 #include <testsuite_hooks.h>
6 // PR libstdc++/108846 std::copy, std::copy_n and std::copy_backward
7 // on potentially overlapping subobjects
10 B(int i
, short j
) : i(i
), j(j
) {}
15 D(int i
, short j
, short x
) : B(i
, j
), x(x
) {}
16 short x
; // Stored in tail padding of B
26 // If this is optimized to memmove it will overwrite tail padding.
27 std::copy_n(src
, 1, dst
);
28 // Check tail padding is unchanged:
30 // Check B subobject was copied:
31 VERIFY(ddst
.i
== 4 && ddst
.j
== 5);
32 #if __cpp_lib_ranges >= 201911L
34 std::ranges::copy_n(src
, 1, dst
);
36 VERIFY(ddst
.i
== 4 && ddst
.j
== 5);
41 B2(int i
, short j
) : i(i
), j(j
) {}
42 B2
& operator=(B2
& b
) { i
= b
.i
; j
= b
.j
; return *this; }
47 D2(int i
, short j
, short x
) : B2(i
, j
), x(x
) {}
48 short x
; // Stored in tail padding of B2
52 test_non_const_copy_assign()
58 // Ensure the not-taken trivial copy path works for this type.
59 std::copy_n(src
, 1, dst
);
60 // Check tail padding is unchanged:
62 // Check B subobject was copied:
63 VERIFY(ddst
.i
== 4 && ddst
.j
== 5);
64 #if __cpp_lib_ranges >= 201911L
66 std::ranges::copy_n(src
, 1, dst
);
68 VERIFY(ddst
.i
== 4 && ddst
.j
== 5);
73 B3(int i
, short j
) : i(i
), j(j
) {}
74 B3
& operator=(B3
& b
) = default;
79 D3(int i
, short j
, short x
) : B3(i
, j
), x(x
) {}
80 short x
; // Stored in tail padding of B3
84 test_non_const_copy_assign_trivial()
90 // If this is optimized to memmove it will overwrite tail padding.
91 std::copy_n(src
, 1, dst
);
92 // Check tail padding is unchanged:
94 // Check B subobject was copied:
95 VERIFY(ddst
.i
== 4 && ddst
.j
== 5);
96 #if __cpp_lib_ranges >= 201911L
98 std::ranges::copy_n(src
, 1, dst
);
100 VERIFY(ddst
.i
== 4 && ddst
.j
== 5);
107 test_non_const_copy_assign();
108 test_non_const_copy_assign_trivial();