| // 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-not ".ANNOTATE \\\(\[^\n\r]*, 5, 0\\\)" "gimple" } } |
| |
| volatile int v; |
| |
| constexpr bool |
| foo () |
| { |
| return false; |
| } |
| |
| struct S |
| { |
| constexpr S () : s (false) {} |
| 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' always evaluates to false in a non-'constexpr' function" "" { target c++20 } } |
| break; |
| case 31: |
| while (!std::is_constant_evaluated ()) {} // { dg-warning "'std::is_constant_evaluated' always evaluates to false in a non-'constexpr' function" "" { target c++20 } } |
| break; |
| case 32: |
| do ; while (!std::is_constant_evaluated ()); // { dg-warning "'std::is_constant_evaluated' always evaluates to false in a non-'constexpr' function" "" { target c++20 } } |
| break; |
| case 33: |
| do {} while (!std::is_constant_evaluated ()); // { dg-warning "'std::is_constant_evaluated' always evaluates to false in a non-'constexpr' function" "" { target c++20 } } |
| break; |
| case 34: |
| for (v = 42; !std::is_constant_evaluated (); ) ; // { dg-warning "'std::is_constant_evaluated' always evaluates to false in a non-'constexpr' function" "" { target c++20 } } |
| break; |
| case 35: |
| for (v = 42; !std::is_constant_evaluated (); ) {} // { dg-warning "'std::is_constant_evaluated' always evaluates to false in a non-'constexpr' function" "" { target c++20 } } |
| break; |
| case 36: |
| for (int w = 42; !std::is_constant_evaluated (); ) ; // { dg-warning "'std::is_constant_evaluated' always evaluates to false in a non-'constexpr' function" "" { target c++20 } } |
| break; |
| case 37: |
| for (int w = 42; !std::is_constant_evaluated (); ) {} // { dg-warning "'std::is_constant_evaluated' always evaluates to false in a non-'constexpr' function" "" { target c++20 } } |
| break; |
| #endif |
| default: |
| break; |
| } |
| } |