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