1// PR sanitizer/63956
2// { dg-do compile }
3// { dg-options "-std=c++14 -fsanitize=undefined,float-divide-by-zero,float-cast-overflow" }
4
5#define SA(X) static_assert((X),#X)
6#define INT_MIN (-__INT_MAX__ - 1)
7
8constexpr int
9fn1 (int a, int b)
10{
11  if (b != 2)
12    a <<= b;
13  return a;
14}
15
16constexpr int i1 = fn1 (5, 3);
17constexpr int i2 = fn1 (5, -2); // { dg-error "is negative" }
18constexpr int i3 = fn1 (5, sizeof (int) * __CHAR_BIT__); // { dg-error "is >= than the precision of the left operand" }
19constexpr int i4 = fn1 (5, 256); // { dg-error "is >= than the precision of the left operand" }
20constexpr int i5 = fn1 (5, 2);
21constexpr int i6 = fn1 (-2, 4); // { dg-error "is negative" }
22constexpr int i7 = fn1 (0, 2);
23
24SA (i1 == 40);
25SA (i5 == 5);
26SA (i7 == 0);
27
28constexpr int
29fn2 (int a, int b)
30{
31  if (b != 2)
32    a >>= b;
33  return a;
34}
35
36constexpr int j1 = fn2 (4, 1);
37constexpr int j2 = fn2 (4, -1); // { dg-error "is negative" }
38constexpr int j3 = fn2 (10, sizeof (int) * __CHAR_BIT__); // { dg-error "is >= than the precision of the left operand" }
39constexpr int j4 = fn2 (1, 256); // { dg-error "is >= than the precision of the left operand" }
40constexpr int j5 = fn2 (5, 2);
41constexpr int j6 = fn2 (-2, 4);
42constexpr int j7 = fn2 (0, 4);
43
44SA (j1 == 2);
45SA (j5 == 5);
46SA (j7 == 0);
47
48constexpr int
49fn3 (int a, int b)
50{
51  if (b != 2)
52    a = a / b;
53  return a;
54}
55
56constexpr int k1 = fn3 (8, 4);
57constexpr int k2 = fn3 (7, 0); // { dg-error "is not a constant expression" }
58constexpr int k3 = fn3 (INT_MIN, -1); // { dg-error "overflow in constant expression" }
59
60SA (k1 == 2);
61
62constexpr float
63fn4 (float a, float b)
64{
65  if (b != 2.0)
66    a = a / b;
67  return a;
68}
69
70constexpr float l1 = fn4 (5.0, 3.0);
71constexpr float l2 = fn4 (7.0, 0.0); // { dg-error "is not a constant expression" }
72
73constexpr int
74fn5 (const int *a, int b)
75{
76  if (b != 2)
77    b = a[b];
78  return b;
79}
80
81constexpr int m1[4] = { 1, 2, 3, 4 };
82constexpr int m2 = fn5 (m1, 3);
83constexpr int m3 = fn5 (m1, 4); // { dg-error "array subscript out of bound" }
84
85constexpr int
86fn6 (const int &a, int b)
87{
88  if (b != 2)
89    b = a;
90  return b;
91}
92
93constexpr int
94fn7 (const int *a, int b)
95{
96  if (b != 3)
97    return fn6 (*a, b);
98  return 7;
99}
100
101constexpr int n1 = 7;
102constexpr int n2 = fn7 (&n1, 5);
103constexpr int n3 = fn7 ((const int *) 0, 8); // { dg-error "is not a constant expression" }
104
105constexpr int
106fn8 (int i)
107{
108  constexpr int g[10] = { };
109  return g[i];
110}
111
112constexpr int o1 = fn8 (9);
113constexpr int o2 = fn8 (10); // { dg-error "array subscript out of bound" }
114
115constexpr int
116fn9 (int a, int b)
117{
118  if (b != 0)
119    return a + b;
120  return a;
121}
122
123constexpr int p1 = fn9 (42, 7);
124constexpr int p2 = fn9 (__INT_MAX__, 1); // { dg-error "overflow in constant expression" }
125constexpr int p3 = fn9 (__INT_MAX__, -1);
126constexpr int p4 = fn9 (INT_MIN, 1);
127constexpr int p5 = fn9 (INT_MIN, -1); // { dg-error "overflow in constant expression" }
128
129SA (p1 == 49);
130SA (p3 == __INT_MAX__ - 1);
131SA (p4 == INT_MIN + 1);
132
133constexpr int
134fn10 (int a, int b)
135{
136  if (b != 0)
137    return a * b;
138  return a;
139}
140
141constexpr int q1 = fn10 (10, 10);
142constexpr int q2 = fn10 (__INT_MAX__, 2); // { dg-error "overflow in constant expression" }
143constexpr int q3 = fn10 (INT_MIN, 2); // { dg-error "overflow in constant expression" }
144constexpr int q4 = fn10 (-1, -1);
145
146SA (q1 == 100);
147SA (q4 == 1);
148
149constexpr int
150fn11 (double d)
151{
152  int i = d;
153  if (i != 0)
154    return i;
155  return i * 2;
156}
157
158constexpr int r1 = fn11 (3.4);
159constexpr int r2 = fn11 (__builtin_inf ()); // { dg-error "overflow in constant expression" }
160
161constexpr int
162fn12 (int i)
163{
164  if (i == 42)
165    __builtin_unreachable (); // { dg-error "is not a constant expression" }
166  return i + 10;
167}
168
169constexpr int s1 = fn12 (1);
170constexpr int s2 = fn12 (42);
171
172SA (s1 == 11);
173