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