Home | History | Annotate | Line # | Download | only in lint1
msg_169.c revision 1.10
      1  1.10  rillig /*	$NetBSD: msg_169.c,v 1.10 2024/12/15 06:04:17 rillig Exp $	*/
      2   1.1  rillig # 3 "msg_169.c"
      3   1.1  rillig 
      4   1.9  rillig // Test for message: possible precedence confusion between '%s' and '%s' [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.9  rillig 	/* expect+1: warning: possible precedence confusion between '<<' and '+' [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.9  rillig 	/* expect+1: warning: possible precedence confusion between '<<' and '+' [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.9  rillig 	/* expect+1: warning: possible precedence confusion between '>>' and '-' [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.9  rillig 	/* expect+1: warning: possible precedence confusion between '>>' and '-' [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.9  rillig 	/* expect+1: warning: possible precedence confusion between '<<' and '+' [169] */
     37   1.6  rillig 	con = (a) + b << c;
     38   1.9  rillig 	/* expect+1: warning: possible precedence confusion between '<<' and '+' [169] */
     39   1.6  rillig 	con = a + (b) << c;
     40   1.9  rillig 	/* expect+1: warning: possible precedence confusion between '<<' and '+' [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.9  rillig 	/* expect+1: warning: possible precedence confusion between '<<' and '+' [169] */
     45   1.6  rillig 	con = ch + b << c;
     46   1.9  rillig 	/* expect+1: warning: possible precedence confusion between '<<' and '+' [169] */
     47   1.6  rillig 	con = a + ch << c;
     48   1.9  rillig 	/* expect+1: warning: possible precedence confusion between '<<' and '+' [169] */
     49   1.6  rillig 	con = a + b << ch;
     50   1.2  rillig }
     51   1.2  rillig 
     52   1.2  rillig void
     53  1.10  rillig confusing_logical(bool a, bool b, bool c, bool d)
     54   1.2  rillig {
     55  1.10  rillig 	bool con, okl, okr, okb, 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.9  rillig 	/* expect+1: warning: possible precedence confusion between '||' and '&&' [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.9  rillig 	/* expect+1: warning: possible precedence confusion between '||' and '&&' [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.10  rillig 
     70  1.10  rillig 	// When both nested operands have confusing precedence, there's only
     71  1.10  rillig 	// a single warning, as that is enough to point to the issue.
     72  1.10  rillig 	/* expect+1: warning: possible precedence confusion between '||' and '&&' [169] */
     73  1.10  rillig 	con = a && b || c && d;
     74  1.10  rillig 	/* expect+1: warning: possible precedence confusion between '||' and '&&' [169] */
     75  1.10  rillig 	okl = (a && b) || c && d;
     76  1.10  rillig 	/* expect+1: warning: possible precedence confusion between '||' and '&&' [169] */
     77  1.10  rillig 	okr = a && b || (c && d);
     78  1.10  rillig 	okb = (a && b) || (c && d);
     79   1.2  rillig }
     80   1.2  rillig 
     81   1.2  rillig void
     82   1.2  rillig confusing_bitwise(unsigned a, unsigned b, unsigned c)
     83   1.2  rillig {
     84   1.2  rillig 	bool con, okl, okr, eql;
     85   1.2  rillig 
     86   1.2  rillig 	eql = a & b & c;
     87   1.2  rillig 	eql = a | b | c;
     88   1.2  rillig 	eql = a ^ b ^ c;
     89   1.2  rillig 
     90   1.9  rillig 	/* expect+1: warning: possible precedence confusion between '|' and '^' [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.9  rillig 	/* expect+1: warning: possible precedence confusion between '|' and '&' [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.9  rillig 	/* expect+1: warning: possible precedence confusion between '|' and '^' [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.9  rillig 	/* expect+1: warning: possible precedence confusion between '^' and '&' [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.9  rillig 	/* expect+1: warning: possible precedence confusion between '|' and '&' [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.9  rillig 	/* expect+1: warning: possible precedence confusion between '^' and '&' [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.9  rillig 	/* expect+1: warning: possible precedence confusion between '&' and '+' [169] */
    121   1.6  rillig 	con = a & b + c;
    122   1.2  rillig 	okl = (a & b) + c;
    123   1.2  rillig 	okr = a & (b + c);
    124   1.2  rillig 
    125   1.9  rillig 	/* expect+1: warning: possible precedence confusion between '|' and '-' [169] */
    126   1.6  rillig 	con = a - b | c;
    127   1.2  rillig 	okl = (a - b) | c;
    128   1.2  rillig 	okr = a - (b | c);
    129   1.2  rillig 
    130   1.2  rillig 	// This looks like a binomial formula but isn't.
    131   1.9  rillig 	/* expect+1: warning: possible precedence confusion between '^' and '+' [169] */
    132   1.6  rillig 	con = a ^ 2 - 2 * a * b + b ^ 2;
    133   1.2  rillig 
    134   1.2  rillig 	// This isn't a binomial formula either since '^' means xor.
    135   1.2  rillig 	con = (a ^ 2) - 2 * a * b + (b ^ 2);
    136   1.2  rillig }
    137   1.2  rillig 
    138   1.2  rillig void
    139   1.2  rillig constant_expressions(void)
    140   1.2  rillig {
    141   1.2  rillig 	unsigned con;
    142   1.2  rillig 
    143   1.2  rillig 	// The check for confusing precedence happens after constant folding.
    144   1.2  rillig 	// Therefore the following lines do not generate warnings.
    145   1.2  rillig 	con = 1 & 2 | 3;
    146   1.2  rillig 	con = 4 << 5 + 6;
    147   1.2  rillig 	con = 7 ^ 8 & 9;
    148   1.2  rillig }
    149   1.2  rillig 
    150   1.2  rillig void
    151   1.2  rillig cast_expressions(char a, char b, char c)
    152   1.2  rillig {
    153   1.2  rillig 	unsigned con;
    154   1.2  rillig 
    155   1.2  rillig 	// Adding casts to the leaf nodes doesn't change anything about the
    156   1.2  rillig 	// confusing precedence.
    157   1.9  rillig 	/* expect+1: warning: possible precedence confusion between '|' and '&' [169] */
    158   1.6  rillig 	con = (unsigned)a | (unsigned)b & (unsigned)c;
    159   1.9  rillig 	/* expect+1: warning: possible precedence confusion between '|' and '&' [169] */
    160   1.6  rillig 	con = (unsigned)a & (unsigned)b | (unsigned)c;
    161   1.2  rillig 
    162   1.2  rillig 	// Adding a cast around the whole calculation doesn't change the
    163   1.2  rillig 	// precedence as well.
    164   1.9  rillig 	/* expect+1: warning: possible precedence confusion between '|' and '&' [169] */
    165   1.6  rillig 	con = (unsigned)(a | b & c);
    166   1.2  rillig 
    167   1.2  rillig 	// Adding a cast around an intermediate result groups the operands
    168   1.2  rillig 	// of the main node, which prevents any confusion about precedence.
    169   1.2  rillig 	con = (unsigned)a | (unsigned)(b & c);
    170   1.2  rillig 	con = a | (unsigned)(b & c);
    171   1.2  rillig 	con = (unsigned)(a | b) & (unsigned)c;
    172   1.2  rillig 	con = (unsigned)(a | b) & c;
    173   1.2  rillig }
    174   1.2  rillig 
    175   1.2  rillig void
    176   1.2  rillig expected_precedence(int a, int b, int c)
    177   1.2  rillig {
    178   1.2  rillig 	int ok;
    179   1.2  rillig 
    180   1.2  rillig 	ok = a + b * c;
    181   1.2  rillig }
    182   1.2  rillig 
    183   1.4  rillig void
    184   1.4  rillig implicit_conversion_to_long(long la, int a)
    185   1.4  rillig {
    186   1.4  rillig 	int ok;
    187   1.4  rillig 
    188   1.9  rillig 	/* expect+1: warning: possible precedence confusion between '|' and '&' [169] */
    189   1.6  rillig 	ok = a & a | la;
    190   1.5  rillig 
    191   1.5  rillig 	/*
    192   1.5  rillig 	 * Before tree.c 1.132 from 2021-01-04, there was a typo in
    193   1.5  rillig 	 * check_precedence_confusion that prevented the right-hand operand
    194   1.5  rillig 	 * from being flagged as possibly confusing if there was an implicit
    195   1.5  rillig 	 * conversion or an explicit cast between the main operator ('|') and
    196   1.5  rillig 	 * the nested operator ('&').
    197   1.5  rillig 	 */
    198   1.9  rillig 	/* expect+1: warning: possible precedence confusion between '|' and '&' [169] */
    199   1.6  rillig 	ok = la | a & a;
    200   1.4  rillig 
    201   1.4  rillig 	ok = (a & a) | la;	/* always ok */
    202   1.4  rillig 	ok = la | (a & a);	/* always ok */
    203   1.4  rillig 
    204   1.4  rillig 	/*
    205   1.4  rillig 	 * Before tree.c 1.132, this expression didn't generate a warning
    206   1.4  rillig 	 * because the right-hand operand was CVT, and there is no confusing
    207   1.4  rillig 	 * precedence between BITOR and CVT.
    208   1.4  rillig 	 *
    209   1.4  rillig 	 * Since tree.c 1.132, this expression doesn't generate a warning
    210   1.4  rillig 	 * because the right-hand operand is parenthesized.  There is no way
    211   1.4  rillig 	 * to have the right operand casted and at the same time not
    212   1.4  rillig 	 * parenthesized since the cast operator has higher precedence.
    213   1.4  rillig 	 *
    214   1.4  rillig 	 * In summary, there is no visible change, but the implementation is
    215   1.4  rillig 	 * now works as intended.
    216   1.4  rillig 	 */
    217   1.4  rillig 	ok = la | (int)(a & a);	/* always ok */
    218   1.4  rillig }
    219