blob: 9491a998ff0258e80aaa4c8c975d26223cc87806 [file] [log] [blame]
// { 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();
}