expr_binary.c revision 1.10 1 /* $NetBSD: expr_binary.c,v 1.10 2025/04/12 15:49:49 rillig Exp $ */
2 # 3 "expr_binary.c"
3
4 /*
5 * Test binary operators.
6 */
7
8 /* lint1-only-if: lp64 */
9 /* lint1-extra-flags: -X 351 */
10
11 struct incompatible { /* just to generate the error message */
12 int member;
13 };
14 void sink(struct incompatible);
15
16 /*
17 * Test the usual arithmetic conversions.
18 *
19 * C99 6.3.1.8 "Usual arithmetic conversions"
20 */
21 void
22 cover_balance(void)
23 {
24 /* expect+1: ... 'pointer to void' ... */
25 sink((void *)0 + 0);
26
27 /* expect+1: ... 'pointer to void' ... */
28 sink(0 + (void *)0);
29
30 /* expect+1: ... 'int' ... */
31 sink(1 + 1);
32
33 /* expect+1: ... 'const int' ... */
34 sink((const int)1 + (volatile int)1);
35
36 /* expect+1: ... 'volatile int' ... */
37 sink((volatile int)1 + (const int)1);
38
39 long double _Complex cldbl = 0.0;
40 double _Complex cdbl = 0.0;
41 float _Complex cflt = 0.0f;
42 /* expect+1: error: invalid type for _Complex [308] */
43 _Complex invalid = 0.0;
44
45 /* expect+1: ... 'long double _Complex' ... */
46 sink(cldbl + 0);
47 /* expect+1: ... 'long double _Complex' ... */
48 sink(0 + cldbl);
49 /* expect+1: ... 'long double _Complex' ... */
50 sink(cldbl + cdbl);
51 /* expect+1: ... 'long double _Complex' ... */
52 sink(cdbl + cldbl);
53
54 /* expect+1: ... 'double _Complex' ... */
55 sink(cdbl + 0);
56 /* expect+1: ... 'double _Complex' ... */
57 sink(0 + cdbl);
58 /* expect+1: ... 'double _Complex' ... */
59 sink(cdbl + cflt);
60 /* expect+1: ... 'double _Complex' ... */
61 sink(cflt + cdbl);
62
63 /* expect+1: ... 'float _Complex' ... */
64 sink(cflt + 0);
65 /* expect+1: ... 'float _Complex' ... */
66 sink(0 + cflt);
67 /* expect+1: ... 'float _Complex' ... */
68 sink(cflt + (__uint128_t)0);
69 /* expect+1: ... 'float _Complex' ... */
70 sink((__uint128_t)0 + cflt);
71
72 /*
73 * The type specifier '_Complex' is only used during parsing, it does
74 * not make it to the expression.
75 */
76 /* expect+1: ... 'double _Complex' ... */
77 sink(invalid + 0);
78
79 /* expect+1: ... 'long double' ... */
80 sink(0.0L + 0);
81 /* expect+1: ... 'long double' ... */
82 sink(0 + 0.0L);
83 /* expect+1: ... 'long double' ... */
84 sink(0.0L + 0.0);
85 /* expect+1: ... 'long double' ... */
86 sink(0.0 + 0.0L);
87
88 /* expect+1: ... 'double' ... */
89 sink(0.0 + 0);
90 /* expect+1: ... 'double' ... */
91 sink(0 + 0.0);
92 /* expect+1: ... 'double' ... */
93 sink(0.0 + 0.0f);
94 /* expect+1: ... 'double' ... */
95 sink(0.0f + 0.0);
96
97 /* expect+1: ... 'float' ... */
98 sink(0.0f + 0);
99 /* expect+1: ... 'float' ... */
100 sink(0 + 0.0f);
101 /* expect+1: ... 'float' ... */
102 sink(0.0f + (__uint128_t)0);
103 /* expect+1: ... 'float' ... */
104 sink((__uint128_t)0 + 0.0f);
105
106 /* expect+1: ... 'unsigned long long' ... */
107 sink(0ULL + 0);
108 /* expect+1: ... 'unsigned long long' ... */
109 sink(0 + 0ULL);
110
111 /* expect+1: ... 'unsigned long long' ... */
112 sink(0ULL + 0LL);
113 /* expect+1: ... 'unsigned long long' ... */
114 sink(0LL + 0ULL);
115
116 /* If the bit-width is the same, prefer the unsigned variant. */
117 /* expect+1: ... 'unsigned long long' ... */
118 sink(0UL + 0LL);
119 /* expect+1: ... 'unsigned long long' ... */
120 sink(0LL + 0UL);
121
122 /*
123 * Ensure that __int128_t is listed in the integer ranks. This table
124 * only becomes relevant when both operands have the same width.
125 */
126 /* expect+1: ... '__uint128_t' ... */
127 sink((__uint128_t)1 + (__int128_t)1);
128 /* expect+1: ... '__uint128_t' ... */
129 sink((__int128_t)1 + (__uint128_t)1);
130 }
131
132 struct point {
133 int x, y;
134 };
135
136 static void
137 return_void(void)
138 {
139 }
140
141 static _Bool
142 return_bool(void)
143 {
144 return sizeof(char) == 1;
145 }
146
147 static struct point
148 return_sou(void)
149 {
150 return (struct point){ 0, 0 };
151 }
152
153 static int
154 return_integer(void)
155 {
156 return 4;
157 }
158
159 static double
160 return_floating(void)
161 {
162 return 3.5;
163 }
164
165 static char *
166 return_pointer(void)
167 {
168 return (void *)0;
169 }
170
171 static inline void
172 op_colon(_Bool cond)
173 {
174 cond ? return_void() : return_void();
175 /* expect+1: warning: incompatible types 'void' and '_Bool' in conditional [126] */
176 cond ? return_void() : return_bool();
177 /* expect+1: warning: incompatible types 'void' and 'struct point' in conditional [126] */
178 cond ? return_void() : return_sou();
179 /* expect+1: warning: incompatible types 'void' and 'int' in conditional [126] */
180 cond ? return_void() : return_integer();
181 /* expect+1: warning: incompatible types 'void' and 'double' in conditional [126] */
182 cond ? return_void() : return_floating();
183 /* expect+1: warning: incompatible types 'void' and 'pointer to char' in conditional [126] */
184 cond ? return_void() : return_pointer();
185 /* expect+1: warning: incompatible types '_Bool' and 'void' in conditional [126] */
186 cond ? return_bool() : return_void();
187 cond ? return_bool() : return_bool();
188 /* expect+1: error: incompatible types '_Bool' and 'struct point' in conditional [126] */
189 cond ? return_bool() : return_sou();
190 cond ? return_bool() : return_integer();
191 cond ? return_bool() : return_floating();
192 /* expect+1: warning: invalid combination of integer '_Bool' and pointer 'pointer to char', op ':' [123] */
193 cond ? return_bool() : return_pointer();
194 // FIXME: GCC doesn't warn, as the 'type mismatch' is not wrong.
195 /* expect+1: warning: incompatible types 'struct point' and 'void' in conditional [126] */
196 cond ? return_sou() : return_void();
197 /* expect+1: error: incompatible types 'struct point' and '_Bool' in conditional [126] */
198 cond ? return_sou() : return_bool();
199 cond ? return_sou() : return_sou();
200 /* expect+1: error: incompatible types 'struct point' and 'int' in conditional [126] */
201 cond ? return_sou() : return_integer();
202 /* expect+1: error: incompatible types 'struct point' and 'double' in conditional [126] */
203 cond ? return_sou() : return_floating();
204 /* expect+1: error: incompatible types 'struct point' and 'pointer to char' in conditional [126] */
205 cond ? return_sou() : return_pointer();
206 /* expect+1: warning: incompatible types 'int' and 'void' in conditional [126] */
207 cond ? return_integer() : return_void();
208 cond ? return_integer() : return_bool();
209 /* expect+1: error: incompatible types 'int' and 'struct point' in conditional [126] */
210 cond ? return_integer() : return_sou();
211 cond ? return_integer() : return_integer();
212 cond ? return_integer() : return_floating();
213 /* expect+1: warning: invalid combination of integer 'int' and pointer 'pointer to char', op ':' [123] */
214 cond ? return_integer() : return_pointer();
215 /* expect+1: warning: incompatible types 'double' and 'void' in conditional [126] */
216 cond ? return_floating() : return_void();
217 cond ? return_floating() : return_bool();
218 /* expect+1: error: incompatible types 'double' and 'struct point' in conditional [126] */
219 cond ? return_floating() : return_sou();
220 cond ? return_floating() : return_integer();
221 cond ? return_floating() : return_floating();
222 /* expect+1: error: incompatible types 'double' and 'pointer to char' in conditional [126] */
223 cond ? return_floating() : return_pointer();
224 /* expect+1: warning: incompatible types 'pointer to char' and 'void' in conditional [126] */
225 cond ? return_pointer() : return_void();
226 /* expect+1: warning: invalid combination of pointer 'pointer to char' and integer '_Bool', op ':' [123] */
227 cond ? return_pointer() : return_bool();
228 /* expect+1: error: incompatible types 'pointer to char' and 'struct point' in conditional [126] */
229 cond ? return_pointer() : return_sou();
230 /* expect+1: warning: invalid combination of pointer 'pointer to char' and integer 'int', op ':' [123] */
231 cond ? return_pointer() : return_integer();
232 /* expect+1: error: incompatible types 'pointer to char' and 'double' in conditional [126] */
233 cond ? return_pointer() : return_floating();
234 cond ? return_pointer() : return_pointer();
235 }
236