Home | History | Annotate | Line # | Download | only in lint1
      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