1 // P0595R1 2 // { dg-do run { target c++14 } } 3 4 template<int N> struct X { int v = N; }; 5 X<__builtin_is_constant_evaluated ()> x; // type X<true> 6 int y = 4; 7 int a = __builtin_is_constant_evaluated () ? y : 1; // initializes a to 1 8 int b = __builtin_is_constant_evaluated () ? 2 : y; // initializes b to 2 9 int c = y + (__builtin_is_constant_evaluated () ? 2 : y); // initializes c to 2*y 10 int d = __builtin_is_constant_evaluated (); // initializes d to 1 11 int e = d + __builtin_is_constant_evaluated (); // initializes e to 1 + 0 12 13 struct false_type { static constexpr bool value = false; }; 14 struct true_type { static constexpr bool value = true; }; 15 template<class T, class U> 16 struct is_same : false_type {}; 17 template<class T> 18 struct is_same<T, T> : true_type {}; 19 20 constexpr int 21 foo (int x) 22 { 23 const int n = __builtin_is_constant_evaluated () ? 13 : 17; // n == 13 24 int m = __builtin_is_constant_evaluated () ? 13 : 17; // m might be 13 or 17 (see below) 25 char arr[n] = {}; // char[13] 26 return m + sizeof (arr) + x; 27 } 28 29 constexpr int 30 bar () 31 { 32 const int n = __builtin_is_constant_evaluated() ? 13 : 17; 33 X<n> x1; 34 X<__builtin_is_constant_evaluated() ? 13 : 17> x2; 35 static_assert (is_same<decltype (x1), decltype (x2)>::value, "x1/x2's type"); 36 return x1.v + x2.v; 37 } 38 39 int p = foo (0); // m == 13; initialized to 26 40 int q = p + foo (0); // m == 17 for this call; initialized to 56 41 static_assert (bar () == 26, "bar"); 42 43 struct S { int a, b; }; 44 45 S s = { __builtin_is_constant_evaluated () ? 2 : 3, y }; 46 S t = { __builtin_is_constant_evaluated () ? 2 : 3, 4 }; 47 48 static_assert (is_same<decltype (x), X<true> >::value, "x's type"); 49 50 int 51 main () 52 { 53 if (a != 1 || b != 2 || c != 8 || d != 1 || e != 1 || p != 26 || q != 56) 54 __builtin_abort (); 55 if (s.a != 3 || s.b != 4 || t.a != 2 || t.b != 4) 56 __builtin_abort (); 57 if (foo (y) != 34) 58 __builtin_abort (); 59 #if __cplusplus >= 201703L 60 if constexpr (foo (0) != 26) 61 __builtin_abort (); 62 #endif 63 constexpr int w = foo (0); 64 if (w != 26) 65 __builtin_abort (); 66 } 67