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