Home | History | Annotate | Line # | Download | only in lint1
msg_160.c revision 1.7
      1  1.7  rillig /*	$NetBSD: msg_160.c,v 1.7 2022/05/18 19:25:12 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.2  rillig /* lint1-extra-flags: -h */
      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.4  rillig 	eval(a == b == z);		/* expect: 160 */
     31  1.4  rillig 
     32  1.5  rillig 	/*
     33  1.5  rillig 	 * Before tree.c 1.201 from 2021-01-31, lint warned about the
     34  1.5  rillig 	 * parenthesized '==' subexpression even though there is nothing
     35  1.5  rillig 	 * surprising about it.
     36  1.5  rillig 	 */
     37  1.5  rillig 	eval((a == b) == z);
     38  1.4  rillig 
     39  1.4  rillig 	/*
     40  1.4  rillig 	 * This one is definitely wrong.  C, unlike Python, does not chain
     41  1.4  rillig 	 * comparison operators in the way mathematicians are used to.
     42  1.4  rillig 	 */
     43  1.4  rillig 	eval(a == b == c);		/* expect: 160 */
     44  1.4  rillig 
     45  1.4  rillig 	/* Parenthesizing one of the operands makes it obvious enough. */
     46  1.5  rillig 	/*
     47  1.5  rillig 	 * Before tree.c 1.201 from 2021-01-31, lint warned about the
     48  1.5  rillig 	 * parenthesized '==' subexpression even though there is nothing
     49  1.5  rillig 	 * surprising about it.
     50  1.5  rillig 	 */
     51  1.5  rillig 	eval((a == b) == c);
     52  1.5  rillig 	/*
     53  1.5  rillig 	 * Before tree.c 1.201 from 2021-01-31, lint warned about the
     54  1.5  rillig 	 * parenthesized '==' subexpression even though there is nothing
     55  1.5  rillig 	 * surprising about it.
     56  1.5  rillig 	 */
     57  1.5  rillig 	eval(a == (b == c));
     58  1.2  rillig }
     59  1.6  rillig 
     60  1.6  rillig void
     61  1.7  rillig assignment_in_comma_expression(int len)
     62  1.6  rillig {
     63  1.6  rillig 
     64  1.7  rillig 	/*
     65  1.7  rillig 	 * No extra parentheses, just a comma operator.
     66  1.7  rillig 	 *
     67  1.7  rillig 	 * The usual interpretation is that the left-hand operand of the
     68  1.7  rillig 	 * comma is a preparation, most often an assignment, and the
     69  1.7  rillig 	 * right-hand operand of the comma is the actual condition.
     70  1.7  rillig 	 */
     71  1.7  rillig 	/* FIXME: The following code is totally fine. */
     72  1.7  rillig 	/* expect+1: warning: operator '==' found where '=' was expected [160] */
     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 	/* FIXME: The following code is totally fine. */
     90  1.7  rillig 	/* expect+1: warning: operator '==' found where '=' was expected [160] */
     91  1.7  rillig 	if ((len = 3 * len + 1, len == 0))
     92  1.7  rillig 		return;
     93  1.7  rillig 
     94  1.7  rillig 	/*
     95  1.7  rillig 	 * If the comma expression is part of a larger expression, the
     96  1.7  rillig 	 * parentheses are required to mark the operator precedence.  The
     97  1.7  rillig 	 * parentheses must therefore not be interpreted as changing the
     98  1.7  rillig 	 * intention from a condition to an assignment.
     99  1.7  rillig 	 */
    100  1.6  rillig 	/* FIXME: The following code is totally fine. */
    101  1.6  rillig 	/* expect+1: warning: operator '==' found where '=' was expected [160] */
    102  1.7  rillig 	if ((len = 3 * len + 1, len == 0) && len < 2)
    103  1.6  rillig 		return;
    104  1.6  rillig }
    105