Home | History | Annotate | Line # | Download | only in lint1
      1  1.10  rillig /*	$NetBSD: msg_160.c,v 1.10 2023/03/28 14:44:35 rillig Exp $	*/
      2   1.1  rillig # 3 "msg_160.c"
      3   1.1  rillig 
      4   1.1  rillig // Test for message: operator '==' found where '=' was expected [160]
      5   1.1  rillig 
      6  1.10  rillig /* lint1-extra-flags: -h -X 351 */
      7   1.2  rillig 
      8   1.2  rillig _Bool
      9   1.2  rillig both_equal_or_unequal(int a, int b, int c, int d)
     10   1.2  rillig {
     11   1.5  rillig 	/*
     12   1.5  rillig 	 * Before tree.c 1.201 from 2021-01-31, lint warned about each of
     13   1.5  rillig 	 * the '==' subexpressions even though there is nothing surprising
     14   1.5  rillig 	 * about them.
     15   1.5  rillig 	 */
     16   1.5  rillig 	return (a == b) == (c == d);
     17   1.4  rillig }
     18   1.4  rillig 
     19   1.4  rillig void
     20   1.4  rillig eval(_Bool);
     21   1.4  rillig 
     22   1.4  rillig void
     23   1.4  rillig unparenthesized(int a, int b, int c, _Bool z)
     24   1.4  rillig {
     25   1.4  rillig 	/*
     26   1.4  rillig 	 * This one might be legitimate since the second '==' has _Bool
     27   1.4  rillig 	 * on both sides.  Parenthesizing its left-hand operand doesn't
     28   1.4  rillig 	 * hurt though.
     29   1.4  rillig 	 */
     30   1.9  rillig 	/* expect+1: warning: operator '==' found where '=' was expected [160] */
     31   1.9  rillig 	eval(a == b == z);
     32   1.4  rillig 
     33   1.5  rillig 	/*
     34   1.5  rillig 	 * Before tree.c 1.201 from 2021-01-31, lint warned about the
     35   1.5  rillig 	 * parenthesized '==' subexpression even though there is nothing
     36   1.5  rillig 	 * surprising about it.
     37   1.5  rillig 	 */
     38   1.5  rillig 	eval((a == b) == z);
     39   1.4  rillig 
     40   1.4  rillig 	/*
     41   1.4  rillig 	 * This one is definitely wrong.  C, unlike Python, does not chain
     42   1.4  rillig 	 * comparison operators in the way mathematicians are used to.
     43   1.4  rillig 	 */
     44   1.9  rillig 	/* expect+1: warning: operator '==' found where '=' was expected [160] */
     45   1.9  rillig 	eval(a == b == c);
     46   1.4  rillig 
     47   1.4  rillig 	/* Parenthesizing one of the operands makes it obvious enough. */
     48   1.5  rillig 	/*
     49   1.5  rillig 	 * Before tree.c 1.201 from 2021-01-31, lint warned about the
     50   1.5  rillig 	 * parenthesized '==' subexpression even though there is nothing
     51   1.5  rillig 	 * surprising about it.
     52   1.5  rillig 	 */
     53   1.5  rillig 	eval((a == b) == c);
     54   1.5  rillig 	/*
     55   1.5  rillig 	 * Before tree.c 1.201 from 2021-01-31, lint warned about the
     56   1.5  rillig 	 * parenthesized '==' subexpression even though there is nothing
     57   1.5  rillig 	 * surprising about it.
     58   1.5  rillig 	 */
     59   1.5  rillig 	eval(a == (b == c));
     60   1.2  rillig }
     61   1.6  rillig 
     62   1.6  rillig void
     63   1.7  rillig assignment_in_comma_expression(int len)
     64   1.6  rillig {
     65   1.6  rillig 
     66   1.7  rillig 	/*
     67   1.7  rillig 	 * No extra parentheses, just a comma operator.
     68   1.7  rillig 	 *
     69   1.7  rillig 	 * The usual interpretation is that the left-hand operand of the
     70   1.7  rillig 	 * comma is a preparation, most often an assignment, and the
     71   1.7  rillig 	 * right-hand operand of the comma is the actual condition.
     72   1.7  rillig 	 */
     73   1.7  rillig 	if (len = 3 * len + 1, len == 0)
     74   1.7  rillig 		return;
     75   1.7  rillig 
     76   1.7  rillig 	/* Seen in bin/csh/dir.c 1.35 from 2020-08-09, line 223. */
     77   1.7  rillig 	/*
     78   1.7  rillig 	 * The extra parentheses are typically used to inform the compiler
     79   1.7  rillig 	 * that an assignment using '=' is intentional, in particular it is
     80   1.7  rillig 	 * not a typo of the comparison operator '=='.
     81   1.7  rillig 	 *
     82   1.7  rillig 	 * The comma operator in a condition is seldom used, which makes it
     83   1.7  rillig 	 * reasonable to assume that the code author selected the operators
     84   1.7  rillig 	 * on purpose.
     85   1.7  rillig 	 *
     86   1.7  rillig 	 * In this case the parentheses are redundant, it's quite possible
     87   1.7  rillig 	 * that they come from a macro expansion though.
     88   1.7  rillig 	 */
     89   1.7  rillig 	if ((len = 3 * len + 1, len == 0))
     90   1.7  rillig 		return;
     91   1.7  rillig 
     92   1.7  rillig 	/*
     93   1.7  rillig 	 * If the comma expression is part of a larger expression, the
     94   1.7  rillig 	 * parentheses are required to mark the operator precedence.  The
     95   1.7  rillig 	 * parentheses must therefore not be interpreted as changing the
     96   1.7  rillig 	 * intention from a condition to an assignment.
     97   1.7  rillig 	 */
     98   1.7  rillig 	if ((len = 3 * len + 1, len == 0) && len < 2)
     99   1.6  rillig 		return;
    100   1.6  rillig }
    101