| // { dg-do run } |
| |
| // Test the problematic cases identified in PR libstdc++/109150 |
| // where the previous std::fill was non-conforming. |
| |
| #include <algorithm> |
| #include <testsuite_hooks.h> |
| |
| const int global = 0; |
| |
| struct X { |
| void operator=(const int& i) { VERIFY(&i == &global); } |
| }; |
| |
| void |
| test_identity_matters() |
| { |
| X x; |
| // Assigning int to X has non-trivial side effects, so we cannot |
| // hoist the load outside the loop, we have to do exactly what the |
| // standard says to do. |
| std::fill(&x, &x+1, global); |
| } |
| |
| struct Y { |
| int i; |
| void operator=(int ii) { i = ii + 1; } |
| }; |
| |
| void |
| test_self_aliasing() |
| { |
| Y y[2] = { }; |
| // Assigning int to X has non-trivial side effects, altering the value |
| // used to fill the later elements. Must not load it outside the loop. |
| std::fill(y, y+2, y[0].i); |
| VERIFY(y[1].i == 2); |
| } |
| |
| struct Z |
| { |
| Z() { } |
| #if __cplusplus >= 201103L |
| explicit Z(const Z&) = default; |
| #endif |
| }; |
| |
| void |
| test_explicit_copy_ctor() |
| { |
| Z z; |
| // The optimization that copies the fill value must use direct-initialization |
| // otherwise this case would be ill-formed due to the explicit constructor. |
| std::fill(&z, &z, z); |
| } |
| |
| int main() |
| { |
| test_identity_matters(); |
| test_self_aliasing(); |
| test_explicit_copy_ctor(); |
| } |