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