Home | History | Annotate | Line # | Download | only in lint1
msg_169.c revision 1.8
      1  1.8  rillig /*	$NetBSD: msg_169.c,v 1.8 2023/07/07 06:03:31 rillig Exp $	*/
      2  1.1  rillig # 3 "msg_169.c"
      3  1.1  rillig 
      4  1.1  rillig // Test for message: precedence confusion possible: parenthesize! [169]
      5  1.1  rillig 
      6  1.8  rillig /* lint1-flags: -g -h -S -w -X 191,351 */
      7  1.2  rillig 
      8  1.2  rillig typedef _Bool bool;
      9  1.2  rillig 
     10  1.2  rillig void
     11  1.2  rillig confusing_shift_arith(unsigned a, unsigned b, unsigned c, unsigned char ch)
     12  1.2  rillig {
     13  1.2  rillig 	unsigned con, okl, okr;
     14  1.2  rillig 
     15  1.6  rillig 	/* expect+1: warning: precedence confusion possible: parenthesize! [169] */
     16  1.6  rillig 	con = a + b << c;
     17  1.2  rillig 	okl = (a + b) << c;
     18  1.2  rillig 	okr = a + (b << c);
     19  1.2  rillig 
     20  1.6  rillig 	/* expect+1: warning: precedence confusion possible: parenthesize! [169] */
     21  1.6  rillig 	con = a << b + c;
     22  1.2  rillig 	okl = (a << b) + c;
     23  1.2  rillig 	okr = a << (b + c);
     24  1.2  rillig 
     25  1.6  rillig 	/* expect+1: warning: precedence confusion possible: parenthesize! [169] */
     26  1.6  rillig 	con = a - b >> c;
     27  1.2  rillig 	okl = (a - b) >> c;
     28  1.2  rillig 	okr = a - (b >> c);
     29  1.2  rillig 
     30  1.6  rillig 	/* expect+1: warning: precedence confusion possible: parenthesize! [169] */
     31  1.6  rillig 	con = a >> b - c;
     32  1.2  rillig 	okl = (a >> b) - c;
     33  1.2  rillig 	okr = a >> (b - c);
     34  1.2  rillig 
     35  1.2  rillig 	// Parenthesizing the inner operands has no effect on the warning.
     36  1.6  rillig 	/* expect+1: warning: precedence confusion possible: parenthesize! [169] */
     37  1.6  rillig 	con = (a) + b << c;
     38  1.6  rillig 	/* expect+1: warning: precedence confusion possible: parenthesize! [169] */
     39  1.6  rillig 	con = a + (b) << c;
     40  1.6  rillig 	/* expect+1: warning: precedence confusion possible: parenthesize! [169] */
     41  1.6  rillig 	con = a + b << (c);
     42  1.2  rillig 
     43  1.2  rillig 	// The usual arithmetic promotions have no effect on the warning.
     44  1.6  rillig 	/* expect+1: warning: precedence confusion possible: parenthesize! [169] */
     45  1.6  rillig 	con = ch + b << c;
     46  1.6  rillig 	/* expect+1: warning: precedence confusion possible: parenthesize! [169] */
     47  1.6  rillig 	con = a + ch << c;
     48  1.6  rillig 	/* expect+1: warning: precedence confusion possible: parenthesize! [169] */
     49  1.6  rillig 	con = a + b << ch;
     50  1.2  rillig }
     51  1.2  rillig 
     52  1.2  rillig void
     53  1.2  rillig confusing_logical(bool a, bool b, bool c)
     54  1.2  rillig {
     55  1.2  rillig 	bool con, okl, okr, eql;
     56  1.2  rillig 
     57  1.2  rillig 	eql = a && b && c;
     58  1.2  rillig 	eql = a || b || c;
     59  1.2  rillig 
     60  1.6  rillig 	/* expect+1: warning: precedence confusion possible: parenthesize! [169] */
     61  1.6  rillig 	con = a && b || c;
     62  1.2  rillig 	okl = (a && b) || c;
     63  1.2  rillig 	okr = a && (b || c);
     64  1.2  rillig 
     65  1.6  rillig 	/* expect+1: warning: precedence confusion possible: parenthesize! [169] */
     66  1.6  rillig 	con = a || b && c;
     67  1.2  rillig 	okl = (a || b) && c;
     68  1.2  rillig 	okr = a || (b && c);
     69  1.2  rillig }
     70  1.2  rillig 
     71  1.2  rillig void
     72  1.2  rillig confusing_bitwise(unsigned a, unsigned b, unsigned c)
     73  1.2  rillig {
     74  1.2  rillig 	bool con, okl, okr, eql;
     75  1.2  rillig 
     76  1.2  rillig 	eql = a & b & c;
     77  1.2  rillig 	eql = a | b | c;
     78  1.2  rillig 	eql = a ^ b ^ c;
     79  1.2  rillig 
     80  1.6  rillig 	/* expect+1: warning: precedence confusion possible: parenthesize! [169] */
     81  1.6  rillig 	con = a | b ^ c;
     82  1.2  rillig 	okl = (a | b) ^ c;
     83  1.2  rillig 	okr = a | (b ^ c);
     84  1.2  rillig 
     85  1.6  rillig 	/* expect+1: warning: precedence confusion possible: parenthesize! [169] */
     86  1.6  rillig 	con = a | b & c;
     87  1.2  rillig 	okl = (a | b) & c;
     88  1.2  rillig 	okr = a | (b & c);
     89  1.2  rillig 
     90  1.6  rillig 	/* expect+1: warning: precedence confusion possible: parenthesize! [169] */
     91  1.6  rillig 	con = a ^ b | c;
     92  1.2  rillig 	okl = (a ^ b) | c;
     93  1.2  rillig 	okr = a ^ (b | c);
     94  1.2  rillig 
     95  1.6  rillig 	/* expect+1: warning: precedence confusion possible: parenthesize! [169] */
     96  1.6  rillig 	con = a ^ b & c;
     97  1.2  rillig 	okl = (a ^ b) & c;
     98  1.2  rillig 	okr = a ^ (b & c);
     99  1.2  rillig 
    100  1.6  rillig 	/* expect+1: warning: precedence confusion possible: parenthesize! [169] */
    101  1.6  rillig 	con = a & b | c;
    102  1.2  rillig 	okl = (a & b) ^ c;
    103  1.2  rillig 	okr = a & (b ^ c);
    104  1.2  rillig 
    105  1.6  rillig 	/* expect+1: warning: precedence confusion possible: parenthesize! [169] */
    106  1.6  rillig 	con = a & b ^ c;
    107  1.2  rillig 	okl = (a & b) ^ c;
    108  1.2  rillig 	okr = a & (b ^ c);
    109  1.2  rillig 
    110  1.6  rillig 	/* expect+1: warning: precedence confusion possible: parenthesize! [169] */
    111  1.6  rillig 	con = a & b + c;
    112  1.2  rillig 	okl = (a & b) + c;
    113  1.2  rillig 	okr = a & (b + c);
    114  1.2  rillig 
    115  1.6  rillig 	/* expect+1: warning: precedence confusion possible: parenthesize! [169] */
    116  1.6  rillig 	con = a - b | c;
    117  1.2  rillig 	okl = (a - b) | c;
    118  1.2  rillig 	okr = a - (b | c);
    119  1.2  rillig 
    120  1.2  rillig 	// This looks like a binomial formula but isn't.
    121  1.6  rillig 	/* expect+1: warning: precedence confusion possible: parenthesize! [169] */
    122  1.6  rillig 	con = a ^ 2 - 2 * a * b + b ^ 2;
    123  1.2  rillig 
    124  1.2  rillig 	// This isn't a binomial formula either since '^' means xor.
    125  1.2  rillig 	con = (a ^ 2) - 2 * a * b + (b ^ 2);
    126  1.2  rillig }
    127  1.2  rillig 
    128  1.2  rillig void
    129  1.2  rillig constant_expressions(void)
    130  1.2  rillig {
    131  1.2  rillig 	unsigned con;
    132  1.2  rillig 
    133  1.2  rillig 	// The check for confusing precedence happens after constant folding.
    134  1.2  rillig 	// Therefore the following lines do not generate warnings.
    135  1.2  rillig 	con = 1 & 2 | 3;
    136  1.2  rillig 	con = 4 << 5 + 6;
    137  1.2  rillig 	con = 7 ^ 8 & 9;
    138  1.2  rillig }
    139  1.2  rillig 
    140  1.2  rillig void
    141  1.2  rillig cast_expressions(char a, char b, char c)
    142  1.2  rillig {
    143  1.2  rillig 	unsigned con;
    144  1.2  rillig 
    145  1.2  rillig 	// Adding casts to the leaf nodes doesn't change anything about the
    146  1.2  rillig 	// confusing precedence.
    147  1.6  rillig 	/* expect+1: warning: precedence confusion possible: parenthesize! [169] */
    148  1.6  rillig 	con = (unsigned)a | (unsigned)b & (unsigned)c;
    149  1.6  rillig 	/* expect+1: warning: precedence confusion possible: parenthesize! [169] */
    150  1.6  rillig 	con = (unsigned)a & (unsigned)b | (unsigned)c;
    151  1.2  rillig 
    152  1.2  rillig 	// Adding a cast around the whole calculation doesn't change the
    153  1.2  rillig 	// precedence as well.
    154  1.6  rillig 	/* expect+1: warning: precedence confusion possible: parenthesize! [169] */
    155  1.6  rillig 	con = (unsigned)(a | b & c);
    156  1.2  rillig 
    157  1.2  rillig 	// Adding a cast around an intermediate result groups the operands
    158  1.2  rillig 	// of the main node, which prevents any confusion about precedence.
    159  1.2  rillig 	con = (unsigned)a | (unsigned)(b & c);
    160  1.2  rillig 	con = a | (unsigned)(b & c);
    161  1.2  rillig 	con = (unsigned)(a | b) & (unsigned)c;
    162  1.2  rillig 	con = (unsigned)(a | b) & c;
    163  1.2  rillig }
    164  1.2  rillig 
    165  1.2  rillig void
    166  1.2  rillig expected_precedence(int a, int b, int c)
    167  1.2  rillig {
    168  1.2  rillig 	int ok;
    169  1.2  rillig 
    170  1.2  rillig 	ok = a + b * c;
    171  1.2  rillig }
    172  1.2  rillig 
    173  1.4  rillig void
    174  1.4  rillig implicit_conversion_to_long(long la, int a)
    175  1.4  rillig {
    176  1.4  rillig 	int ok;
    177  1.4  rillig 
    178  1.6  rillig 	/* expect+1: warning: precedence confusion possible: parenthesize! [169] */
    179  1.6  rillig 	ok = a & a | la;
    180  1.5  rillig 
    181  1.5  rillig 	/*
    182  1.5  rillig 	 * Before tree.c 1.132 from 2021-01-04, there was a typo in
    183  1.5  rillig 	 * check_precedence_confusion that prevented the right-hand operand
    184  1.5  rillig 	 * from being flagged as possibly confusing if there was an implicit
    185  1.5  rillig 	 * conversion or an explicit cast between the main operator ('|') and
    186  1.5  rillig 	 * the nested operator ('&').
    187  1.5  rillig 	 */
    188  1.6  rillig 	/* expect+1: warning: precedence confusion possible: parenthesize! [169] */
    189  1.6  rillig 	ok = la | a & a;
    190  1.4  rillig 
    191  1.4  rillig 	ok = (a & a) | la;	/* always ok */
    192  1.4  rillig 	ok = la | (a & a);	/* always ok */
    193  1.4  rillig 
    194  1.4  rillig 	/*
    195  1.4  rillig 	 * Before tree.c 1.132, this expression didn't generate a warning
    196  1.4  rillig 	 * because the right-hand operand was CVT, and there is no confusing
    197  1.4  rillig 	 * precedence between BITOR and CVT.
    198  1.4  rillig 	 *
    199  1.4  rillig 	 * Since tree.c 1.132, this expression doesn't generate a warning
    200  1.4  rillig 	 * because the right-hand operand is parenthesized.  There is no way
    201  1.4  rillig 	 * to have the right operand casted and at the same time not
    202  1.4  rillig 	 * parenthesized since the cast operator has higher precedence.
    203  1.4  rillig 	 *
    204  1.4  rillig 	 * In summary, there is no visible change, but the implementation is
    205  1.4  rillig 	 * now works as intended.
    206  1.4  rillig 	 */
    207  1.4  rillig 	ok = la | (int)(a & a);	/* always ok */
    208  1.4  rillig }
    209