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