msg_160.c revision 1.9 1 1.9 rillig /* $NetBSD: msg_160.c,v 1.9 2022/06/16 16:58:36 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.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