Home | History | Annotate | Line # | Download | only in lint1
expr_binary.c revision 1.8.2.1
      1  1.8.2.1  perseant /*	$NetBSD: expr_binary.c,v 1.8.2.1 2025/08/02 05:58:14 perseant 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.8.2.1  perseant static void
    137  1.8.2.1  perseant return_void(void)
    138  1.8.2.1  perseant {
    139  1.8.2.1  perseant }
    140  1.8.2.1  perseant 
    141  1.8.2.1  perseant static _Bool
    142  1.8.2.1  perseant return_bool(void)
    143  1.8.2.1  perseant {
    144  1.8.2.1  perseant 	return sizeof(char) == 1;
    145  1.8.2.1  perseant }
    146  1.8.2.1  perseant 
    147      1.8    rillig static struct point
    148  1.8.2.1  perseant 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.8.2.1  perseant static int
    154  1.8.2.1  perseant return_integer(void)
    155      1.8    rillig {
    156  1.8.2.1  perseant 	return 4;
    157  1.8.2.1  perseant }
    158  1.8.2.1  perseant 
    159  1.8.2.1  perseant static double
    160  1.8.2.1  perseant return_floating(void)
    161  1.8.2.1  perseant {
    162  1.8.2.1  perseant 	return 3.5;
    163  1.8.2.1  perseant }
    164  1.8.2.1  perseant 
    165  1.8.2.1  perseant static char *
    166  1.8.2.1  perseant return_pointer(void)
    167  1.8.2.1  perseant {
    168  1.8.2.1  perseant 	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.8.2.1  perseant 	cond ? return_void() : return_void();
    175  1.8.2.1  perseant 	/* expect+1: warning: incompatible types 'void' and '_Bool' in conditional [126] */
    176  1.8.2.1  perseant 	cond ? return_void() : return_bool();
    177  1.8.2.1  perseant 	/* expect+1: warning: incompatible types 'void' and 'struct point' in conditional [126] */
    178  1.8.2.1  perseant 	cond ? return_void() : return_sou();
    179  1.8.2.1  perseant 	/* expect+1: warning: incompatible types 'void' and 'int' in conditional [126] */
    180  1.8.2.1  perseant 	cond ? return_void() : return_integer();
    181  1.8.2.1  perseant 	/* expect+1: warning: incompatible types 'void' and 'double' in conditional [126] */
    182  1.8.2.1  perseant 	cond ? return_void() : return_floating();
    183  1.8.2.1  perseant 	/* expect+1: warning: incompatible types 'void' and 'pointer to char' in conditional [126] */
    184  1.8.2.1  perseant 	cond ? return_void() : return_pointer();
    185  1.8.2.1  perseant 	/* expect+1: warning: incompatible types '_Bool' and 'void' in conditional [126] */
    186  1.8.2.1  perseant 	cond ? return_bool() : return_void();
    187  1.8.2.1  perseant 	cond ? return_bool() : return_bool();
    188  1.8.2.1  perseant 	/* expect+1: error: incompatible types '_Bool' and 'struct point' in conditional [126] */
    189  1.8.2.1  perseant 	cond ? return_bool() : return_sou();
    190  1.8.2.1  perseant 	cond ? return_bool() : return_integer();
    191  1.8.2.1  perseant 	cond ? return_bool() : return_floating();
    192  1.8.2.1  perseant 	/* expect+1: warning: invalid combination of integer '_Bool' and pointer 'pointer to char', op ':' [123] */
    193  1.8.2.1  perseant 	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.8.2.1  perseant 	cond ? return_sou() : return_void();
    197  1.8.2.1  perseant 	/* expect+1: error: incompatible types 'struct point' and '_Bool' in conditional [126] */
    198  1.8.2.1  perseant 	cond ? return_sou() : return_bool();
    199  1.8.2.1  perseant 	cond ? return_sou() : return_sou();
    200  1.8.2.1  perseant 	/* expect+1: error: incompatible types 'struct point' and 'int' in conditional [126] */
    201  1.8.2.1  perseant 	cond ? return_sou() : return_integer();
    202  1.8.2.1  perseant 	/* expect+1: error: incompatible types 'struct point' and 'double' in conditional [126] */
    203  1.8.2.1  perseant 	cond ? return_sou() : return_floating();
    204  1.8.2.1  perseant 	/* expect+1: error: incompatible types 'struct point' and 'pointer to char' in conditional [126] */
    205  1.8.2.1  perseant 	cond ? return_sou() : return_pointer();
    206  1.8.2.1  perseant 	/* expect+1: warning: incompatible types 'int' and 'void' in conditional [126] */
    207  1.8.2.1  perseant 	cond ? return_integer() : return_void();
    208  1.8.2.1  perseant 	cond ? return_integer() : return_bool();
    209  1.8.2.1  perseant 	/* expect+1: error: incompatible types 'int' and 'struct point' in conditional [126] */
    210  1.8.2.1  perseant 	cond ? return_integer() : return_sou();
    211  1.8.2.1  perseant 	cond ? return_integer() : return_integer();
    212  1.8.2.1  perseant 	cond ? return_integer() : return_floating();
    213  1.8.2.1  perseant 	/* expect+1: warning: invalid combination of integer 'int' and pointer 'pointer to char', op ':' [123] */
    214  1.8.2.1  perseant 	cond ? return_integer() : return_pointer();
    215  1.8.2.1  perseant 	/* expect+1: warning: incompatible types 'double' and 'void' in conditional [126] */
    216  1.8.2.1  perseant 	cond ? return_floating() : return_void();
    217  1.8.2.1  perseant 	cond ? return_floating() : return_bool();
    218  1.8.2.1  perseant 	/* expect+1: error: incompatible types 'double' and 'struct point' in conditional [126] */
    219  1.8.2.1  perseant 	cond ? return_floating() : return_sou();
    220  1.8.2.1  perseant 	cond ? return_floating() : return_integer();
    221  1.8.2.1  perseant 	cond ? return_floating() : return_floating();
    222  1.8.2.1  perseant 	/* expect+1: error: incompatible types 'double' and 'pointer to char' in conditional [126] */
    223  1.8.2.1  perseant 	cond ? return_floating() : return_pointer();
    224  1.8.2.1  perseant 	/* expect+1: warning: incompatible types 'pointer to char' and 'void' in conditional [126] */
    225  1.8.2.1  perseant 	cond ? return_pointer() : return_void();
    226  1.8.2.1  perseant 	/* expect+1: warning: invalid combination of pointer 'pointer to char' and integer '_Bool', op ':' [123] */
    227  1.8.2.1  perseant 	cond ? return_pointer() : return_bool();
    228  1.8.2.1  perseant 	/* expect+1: error: incompatible types 'pointer to char' and 'struct point' in conditional [126] */
    229  1.8.2.1  perseant 	cond ? return_pointer() : return_sou();
    230  1.8.2.1  perseant 	/* expect+1: warning: invalid combination of pointer 'pointer to char' and integer 'int', op ':' [123] */
    231  1.8.2.1  perseant 	cond ? return_pointer() : return_integer();
    232  1.8.2.1  perseant 	/* expect+1: error: incompatible types 'pointer to char' and 'double' in conditional [126] */
    233  1.8.2.1  perseant 	cond ? return_pointer() : return_floating();
    234  1.8.2.1  perseant 	cond ? return_pointer() : return_pointer();
    235      1.8    rillig }
    236