aboutsummaryrefslogtreecommitdiff
path: root/gcc/testsuite/g++.dg/ubsan/pr63956.C
blob: 25db8a40e520587f506f5aeede92fa370f7c31df (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
// PR sanitizer/63956
// { dg-do compile }
// { dg-options "-std=c++14 -fsanitize=undefined,float-divide-by-zero,float-cast-overflow" }

#define SA(X) static_assert((X),#X)
#define INT_MIN (-__INT_MAX__ - 1)

constexpr int
fn1 (int a, int b)
{
  if (b != 2)
    a <<= b;
    // { dg-error "5 << -2.. is negative" "" { target *-*-* } 12 }
    // { dg-error "is >= than the precision of the left operand" "" { target *-*-* } 12 }
    // { dg-error "-2 << 4.. is negative" "" { target *-*-* } 12 }
  return a;
}

constexpr int i1 = fn1 (5, 3);
constexpr int i2 = fn1 (5, -2); // { dg-message "in constexpr expansion" }
constexpr int i3 = fn1 (5, sizeof (int) * __CHAR_BIT__); // { dg-message "in constexpr expansion" }
constexpr int i4 = fn1 (5, 256); // { dg-message "in constexpr expansion" }
constexpr int i5 = fn1 (5, 2);
constexpr int i6 = fn1 (-2, 4); // { dg-message "in constexpr expansion" }
constexpr int i7 = fn1 (0, 2);

SA (i1 == 40);
SA (i5 == 5);
SA (i7 == 0);

constexpr int
fn2 (int a, int b)
{
  if (b != 2)
    a >>= b;
    // { dg-error "4 >> -1.. is negative" "" { target *-*-* } 35 }
    // { dg-error "is >= than the precision of the left operand" "" { target *-*-* } 35 }

  return a;
}

constexpr int j1 = fn2 (4, 1);
constexpr int j2 = fn2 (4, -1); // { dg-message "in constexpr expansion" }
constexpr int j3 = fn2 (10, sizeof (int) * __CHAR_BIT__); // { dg-message "in constexpr expansion" }
constexpr int j4 = fn2 (1, 256); // { dg-message "in constexpr expansion" }
constexpr int j5 = fn2 (5, 2);
constexpr int j6 = fn2 (-2, 4);
constexpr int j7 = fn2 (0, 4);

SA (j1 == 2);
SA (j5 == 5);
SA (j7 == 0);

constexpr int
fn3 (int a, int b)
{
  if (b != 2)
    a = a / b; // { dg-error "..7 / 0.. is not a constant expression" }
  return a;
}

constexpr int k1 = fn3 (8, 4);
constexpr int k2 = fn3 (7, 0); // { dg-message "in constexpr expansion" }
constexpr int k3 = fn3 (INT_MIN, -1); // { dg-error "overflow in constant expression" }

SA (k1 == 2);

constexpr float
fn4 (float a, float b)
{
  if (b != 2.0)
    a = a / b; // { dg-error "is not a constant expression" }
  return a;
}

constexpr float l1 = fn4 (5.0, 3.0);
constexpr float l2 = fn4 (7.0, 0.0); // { dg-message "in constexpr expansion" }

constexpr int
fn5 (const int *a, int b)
{
  if (b != 2)
    b = a[b];
  return b;
}

constexpr int m1[4] = { 1, 2, 3, 4 };
constexpr int m2 = fn5 (m1, 3);
constexpr int m3 = fn5 (m1, 4); // { dg-error "array subscript" }

constexpr int
fn6 (const int &a, int b)
{
  if (b != 2)
    b = a;  // { dg-error "is not a constant expression" }
  return b;
}

constexpr int
fn7 (const int *a, int b)
{
  if (b != 3)
    return fn6 (*a, b);
  return 7;
}

constexpr int n1 = 7;
constexpr int n2 = fn7 (&n1, 5);
constexpr int n3 = fn7 ((const int *) 0, 8);

constexpr int
fn8 (int i)
{
  constexpr int g[10] = { };
  return g[i];
}

constexpr int o1 = fn8 (9);
constexpr int o2 = fn8 (10); // { dg-error "array subscript" }

constexpr int
fn9 (int a, int b)
{
  if (b != 0)
    return a + b;
  return a;
}

constexpr int p1 = fn9 (42, 7);
constexpr int p2 = fn9 (__INT_MAX__, 1); // { dg-error "overflow in constant expression" }
constexpr int p3 = fn9 (__INT_MAX__, -1);
constexpr int p4 = fn9 (INT_MIN, 1);
constexpr int p5 = fn9 (INT_MIN, -1); // { dg-error "overflow in constant expression" }

SA (p1 == 49);
SA (p3 == __INT_MAX__ - 1);
SA (p4 == INT_MIN + 1);

constexpr int
fn10 (int a, int b)
{
  if (b != 0)
    return a * b;
  return a;
}

constexpr int q1 = fn10 (10, 10);
constexpr int q2 = fn10 (__INT_MAX__, 2); // { dg-error "overflow in constant expression" }
constexpr int q3 = fn10 (INT_MIN, 2); // { dg-error "overflow in constant expression" }
constexpr int q4 = fn10 (-1, -1);

SA (q1 == 100);
SA (q4 == 1);

constexpr int
fn11 (double d)
{
  int i = d;
  if (i != 0)
    return i;
  return i * 2;
}

constexpr int r1 = fn11 (3.4);
constexpr int r2 = fn11 (__builtin_inf ()); // { dg-error "overflow in constant expression" }

constexpr int
fn12 (int i)
{
  if (i == 42)
    __builtin_unreachable (); // { dg-error "is not a constant expression" }
  return i + 10;
}

constexpr int s1 = fn12 (1);
constexpr int s2 = fn12 (42);

SA (s1 == 11);