blob: 288a736e4ded88dbbd84ec1726ccc55e83a3a956 [file] [log] [blame]
// P2809R3 - Trivial infinite loops are not Undefined Behavior
// { dg-do compile { target c++11 } }
// { dg-additional-options "-fdump-tree-gimple -fno-inline -Wtautological-compare -O2" }
// { dg-final { scan-tree-dump-times ".ANNOTATE \\\(\[^\n\r]*, 5, 0\\\)" 32 "gimple" { target c++20 } } }
// { dg-final { scan-tree-dump-times ".ANNOTATE \\\(\[^\n\r]*, 5, 0\\\)" 16 "gimple" { target c++17_down } } }
volatile int v;
constexpr bool
foo ()
{
return true;
}
struct S
{
constexpr S () : s (true) {}
constexpr operator bool () const { return s; }
bool s;
};
#if __cplusplus >= 202002L
namespace std {
constexpr inline bool
is_constant_evaluated () noexcept
{
#if __cpp_if_consteval >= 202106L
if consteval { return true; } else { return false; }
#else
return __builtin_is_constant_evaluated ();
#endif
}
}
constexpr bool
baz ()
{
return std::is_constant_evaluated ();
}
#endif
void
bar (int x)
{
switch (x)
{
case 0:
while (foo ()) ;
break;
case 1:
while (foo ()) {}
break;
case 2:
do ; while (foo ());
break;
case 3:
do {} while (foo ());
break;
case 4:
for (v = 42; foo (); ) ;
break;
case 5:
for (v = 42; foo (); ) {}
break;
case 6:
for (int w = 42; foo (); ) ;
break;
case 7:
for (int w = 42; foo (); ) {}
break;
case 10:
while (S {}) ;
break;
case 11:
while (S {}) {}
break;
case 12:
do ; while (S {});
break;
case 13:
do {} while (S {});
break;
case 14:
for (v = 42; S {}; ) ;
break;
case 15:
for (v = 42; S {}; ) {}
break;
case 16:
for (int w = 42; S {}; ) ;
break;
case 17:
for (int w = 42; S {}; ) {}
break;
#if __cplusplus >= 202002L
case 20:
while (baz ()) ;
break;
case 21:
while (baz ()) {}
break;
case 22:
do ; while (baz ());
break;
case 23:
do {} while (baz ());
break;
case 24:
for (v = 42; baz (); ) ;
break;
case 25:
for (v = 42; baz (); ) {}
break;
case 26:
for (int w = 42; baz (); ) ;
break;
case 27:
for (int w = 42; baz (); ) {}
break;
case 30:
while (std::is_constant_evaluated ()) ; // { dg-warning "'std::is_constant_evaluated' evaluates to true when checking if trivially empty iteration statement is trivial infinite loop" "" { target c++20 } }
break; // { dg-message "and evaluates to false when actually evaluating the condition in non-'constexpr' function" "" { target c++20 } .-1 }
case 31:
while (std::is_constant_evaluated ()) {} // { dg-warning "'std::is_constant_evaluated' evaluates to true when checking if trivially empty iteration statement is trivial infinite loop" "" { target c++20 } }
break; // { dg-message "and evaluates to false when actually evaluating the condition in non-'constexpr' function" "" { target c++20 } .-1 }
case 32:
do ; while (std::is_constant_evaluated ()); // { dg-warning "'std::is_constant_evaluated' evaluates to true when checking if trivially empty iteration statement is trivial infinite loop" "" { target c++20 } }
break; // { dg-message "and evaluates to false when actually evaluating the condition in non-'constexpr' function" "" { target c++20 } .-1 }
case 33:
do {} while (std::is_constant_evaluated ()); // { dg-warning "'std::is_constant_evaluated' evaluates to true when checking if trivially empty iteration statement is trivial infinite loop" "" { target c++20 } }
break; // { dg-message "and evaluates to false when actually evaluating the condition in non-'constexpr' function" "" { target c++20 } .-1 }
case 34:
for (v = 42; std::is_constant_evaluated (); ) ; // { dg-warning "'std::is_constant_evaluated' evaluates to true when checking if trivially empty iteration statement is trivial infinite loop" "" { target c++20 } }
break; // { dg-message "and evaluates to false when actually evaluating the condition in non-'constexpr' function" "" { target c++20 } .-1 }
case 35:
for (v = 42; std::is_constant_evaluated (); ) {} // { dg-warning "'std::is_constant_evaluated' evaluates to true when checking if trivially empty iteration statement is trivial infinite loop" "" { target c++20 } }
break; // { dg-message "and evaluates to false when actually evaluating the condition in non-'constexpr' function" "" { target c++20 } .-1 }
case 36:
for (int w = 42; std::is_constant_evaluated (); ) ; // { dg-warning "'std::is_constant_evaluated' evaluates to true when checking if trivially empty iteration statement is trivial infinite loop" "" { target c++20 } }
break; // { dg-message "and evaluates to false when actually evaluating the condition in non-'constexpr' function" "" { target c++20 } .-1 }
case 37:
for (int w = 42; std::is_constant_evaluated (); ) {} // { dg-warning "'std::is_constant_evaluated' evaluates to true when checking if trivially empty iteration statement is trivial infinite loop" "" { target c++20 } }
break; // { dg-message "and evaluates to false when actually evaluating the condition in non-'constexpr' function" "" { target c++20 } .-1 }
#endif
default:
break;
}
}