msg_129.c revision 1.7 1 /* $NetBSD: msg_129.c,v 1.7 2023/03/28 14:44:34 rillig Exp $ */
2 # 3 "msg_129.c"
3
4 // Test for message: expression has null effect [129]
5
6 /* lint1-extra-flags: -h -X 351 */
7
8 typedef unsigned char uint8_t;
9 typedef unsigned int uint32_t;
10
11 _Bool side_effect(void);
12
13 /*
14 * Before tree.c 1.198 from 2021-01-30, the nested comma operators were
15 * wrongly reported as having no side effect.
16 *
17 * The bug was that has_side_effect did not properly examine the sub-nodes.
18 * The ',' operator itself has m_has_side_effect == false since it depends
19 * on its operands whether the ',' actually has side effects. For nested ','
20 * operators, the function did not evaluate the operands deeply but only did
21 * a quick shallow test on the m_has_side_effect property. Since that is
22 * false, lint thought that the whole expression would have no side effect.
23 */
24 void
25 uint8_buffer_write_uint32(uint8_t *c, uint32_t l)
26 {
27 (*(c++) = (uint8_t)(l & 0xff),
28 *(c++) = (uint8_t)((l >> 8L) & 0xff),
29 *(c++) = (uint8_t)((l >> 16L) & 0xff),
30 *(c++) = (uint8_t)((l >> 24L) & 0xff));
31 }
32
33 void
34 operator_comma(void)
35 {
36 side_effect(), 0; /* the 0 is redundant */
37 /* expect+1: warning: expression has null effect [129] */
38 0, side_effect();
39
40 if (side_effect(), 0) /* the 0 controls the 'if' */
41 return;
42 /* expect+1: warning: expression has null effect [129] */
43 if (0, side_effect())
44 return;
45 }
46
47 void
48 legitimate_use_cases(int arg)
49 {
50 int local = 3;
51
52 /*
53 * This expression is commonly used to mark the argument as
54 * deliberately unused.
55 */
56 (void)arg;
57
58 /*
59 * This expression is commonly used to mark the local variable as
60 * deliberately unused. This situation occurs when the local
61 * variable is only used in some but not all compile-time selectable
62 * variants of the code, such as in debugging mode, and writing down
63 * the exact conditions would complicate the code unnecessarily.
64 */
65 (void)local;
66
67 /* This is a short-hand notation for a do-nothing command. */
68 (void)0;
69
70 /*
71 * At the point where lint checks for expressions having a null
72 * effect, constants have been folded, therefore the following
73 * expression is considered safe as well. It does not appear in
74 * practice though.
75 */
76 (void)(3 - 3);
77
78 /*
79 * This variant of the do-nothing command is commonly used in
80 * preprocessor macros since it works nicely with if-else and if-then
81 * statements. It is longer than the above variant though.
82 */
83 do {
84 } while (0);
85
86 /*
87 * Only the expression '(void)0' is common, other expressions are
88 * unusual enough to warrant a warning.
89 */
90 /* expect+1: warning: expression has null effect [129] */
91 (void)13;
92
93 /* Double casts are unusual enough to warrant a warning. */
94 /* expect+1: warning: expression has null effect [129] */
95 (void)(void)0;
96 }
97