blob: 3caf00d412ff169b41b6754600c53249bd1d2ae7 [file] [log] [blame]
// PR c++/94695
// { dg-do compile { target c++11 } }
// { dg-options "-Wrange-loop-construct" }
#include <initializer_list>
struct Small {
char arr[64];
};
struct Big_aggr {
char arr[65];
};
struct Big_triv_copy {
char arr[65];
Big_triv_copy() { }
};
struct Big {
char arr[65];
Big () = default;
Big(const Big&);
};
struct Foo { };
struct Bar {
char arr[100];
Bar(Foo);
Bar(int);
operator int();
};
template<typename T>
struct It {
T operator*();
It operator++();
bool operator!=(const It);
};
template<typename T>
struct Cont {
using I = It<T>;
I begin();
I end();
};
#define TEST \
void fn_macro() \
{ \
Cont<Bar &> cont_bar_ref; \
for (const Bar x : cont_bar_ref) { (void) x; } \
}
TEST
Cont<Bar &>& foo ();
Cont<Bar &> foo2 ();
void
fn1 ()
{
for (const auto x : foo () ) { (void) x; } // { dg-warning "creates a copy" }
for (const auto x : foo2 () ) { (void) x; } // { dg-warning "creates a copy" }
Small s{};
Small sa[5] = { };
for (const auto x : sa) { (void) x; }
for (const auto x : { s, s, s }) { (void) x; }
Big_aggr b{};
Big_aggr ba[5] = { };
for (const auto x : ba) { (void) x; } // { dg-warning "creates a copy" }
for (const auto x : { b, b, b }) { (void) x; } // { dg-warning "creates a copy" }
Big_triv_copy bt{};
Big_triv_copy bta[5];
for (const auto x : bta) { (void) x; } // { dg-warning "creates a copy" }
for (const auto x : { bt, bt, bt }) { (void) x; } // { dg-warning "creates a copy" }
Big b2;
Big ba2[5];
for (const auto x : ba2) { (void) x; } // { dg-warning "creates a copy" }
for (const auto x : { b2, b2, b2 }) { (void) x; } // { dg-warning "creates a copy" }
}
void
fn2 ()
{
Cont<int> cont_int;
for (const auto x : cont_int) { (void) x; }
for (const int x : cont_int) { (void) x; }
for (int x : cont_int) { (void) x; }
for (const auto &x : cont_int) { (void) x; }
for (double x : cont_int) { (void) x; }
for (const double x : cont_int) { (void) x; }
for (const Bar x : cont_int) { (void) x; }
for (Bar x : cont_int) { (void) x; }
}
void
fn3 ()
{
Cont<int &> cont_int_ref;
for (const int x : cont_int_ref) { (void) x; }
for (int x : cont_int_ref) { (void) x; }
for (const double x : cont_int_ref) { (void) x; }
for (double x : cont_int_ref) { (void) x; }
for (const Bar x : cont_int_ref) { (void) x; }
for (Bar x : cont_int_ref) { (void) x; }
}
void
fn4 ()
{
Cont<Bar> cont_bar;
for (const Bar x : cont_bar) { (void) x; }
for (Bar x : cont_bar) { (void) x; }
for (const int x : cont_bar) { (void) x; }
for (int x : cont_bar) { (void) x; }
}
void
fn5 ()
{
Cont<Bar&> cont_bar_ref;
for (const Bar x : cont_bar_ref) { (void) x; } // { dg-warning "creates a copy" }
for (Bar x : cont_bar_ref) { (void) x; }
for (const int x : cont_bar_ref) { (void) x; }
for (int x : cont_bar_ref) { (void) x; }
}
void
fn6 ()
{
Cont<Foo> cont_foo;
for (const Bar x : cont_foo) { (void) x; }
for (Bar x : cont_foo) { (void) x; }
}
void
fn7 ()
{
Cont<Foo &> cont_foo_ref;
for (const Bar x : cont_foo_ref) { (void) x; }
for (Bar x : cont_foo_ref) { (void) x; }
}
void
fn8 ()
{
double arr[2];
for (const double x : arr) { (void) x; }
for (double x : arr) { (void) x; }
for (const int x : arr) { (void) x; }
for (int x : arr) { (void) x; }
for (const Bar x : arr) { (void) x; }
for (Bar x : arr) { (void) x; }
}
void
fn9 ()
{
Foo foo[2];
for (const Foo x : foo) { (void) x; }
for (Foo x : foo) { (void) x; }
for (const Bar x : foo) { (void) x; }
for (Bar x : foo) { (void) x; }
}
void
fn10 ()
{
Bar bar[2] = { 1, 2 };
for (const Bar x : bar) { (void) x; } // { dg-warning "creates a copy" }
for (Bar x : bar) { (void) x; }
for (const int x : bar) { (void) x; }
for (int x : bar) { (void) x; }
}
template<typename T>
void
fn11 ()
{
Cont<Bar> cont_bar;
for (const Bar x : cont_bar) { (void) x; }
Cont<Bar&> cont_bar_ref;
for (const Bar x : cont_bar_ref) { (void) x; } // { dg-warning "creates a copy" }
Cont<T> cont_dep;
for (const T x : cont_dep) { (void) x; }
}
template<typename T>
void
fn12 ()
{
for (const auto x : { T{} }) { (void) x; } // { dg-warning "creates a copy" }
}
void
invoke ()
{
fn11<int> ();
fn12<Big> ();
}