xref: /netbsd-src/tests/usr.bin/xlint/lint1/msg_115.c (revision b2baa50111d645353fa30b4deab0f79d93650c8c)
1 /*	$NetBSD: msg_115.c,v 1.11 2023/03/28 14:44:34 rillig Exp $	*/
2 # 3 "msg_115.c"
3 
4 // Test for message: %soperand of '%s' must be modifiable lvalue [115]
5 
6 /* lint1-extra-flags: -X 351 */
7 
8 void
example(const int * const_ptr)9 example(const int *const_ptr)
10 {
11 
12 	/* expect+1: warning: left operand of '=' must be modifiable lvalue [115] */
13 	*const_ptr = 3;
14 	/* expect+1: warning: left operand of '+=' must be modifiable lvalue [115] */
15 	*const_ptr += 1;
16 	/* expect+1: warning: left operand of '-=' must be modifiable lvalue [115] */
17 	*const_ptr -= 4;
18 	/* expect+1: warning: left operand of '*=' must be modifiable lvalue [115] */
19 	*const_ptr *= 1;
20 	/* expect+1: warning: left operand of '/=' must be modifiable lvalue [115] */
21 	*const_ptr /= 5;
22 	/* expect+1: warning: left operand of '%=' must be modifiable lvalue [115] */
23 	*const_ptr %= 9;
24 	/* expect+1: warning: operand of 'x++' must be modifiable lvalue [115] */
25 	(*const_ptr)++;
26 
27 	/* In the next example, the left operand is not an lvalue at all. */
28 	/* expect+1: error: left operand of '=' must be lvalue [114] */
29 	(const_ptr + 3) = const_ptr;
30 }
31 
32 typedef struct {
33 	int const member;
34 } const_member;
35 
36 void take_const_member(const_member);
37 
38 /*
39  * Before init.c 1.208 from 2021-08-14 and decl.c 1.221 from 2021-08-10,
40  * lint issued a wrong "warning: left operand of '%s' must be modifiable
41  * lvalue", even in cases where the left operand was being initialized
42  * instead of overwritten.
43  *
44  * See initialization_expr_using_op, typeok_assign, has_constant_member.
45  * See C99 6.2.5p25.
46  */
47 const_member
initialize_const_struct_member(void)48 initialize_const_struct_member(void)
49 {
50 	/* In a simple initialization, const members can be assigned. */
51 	const_member cm1 = (const_member) { 12345 };
52 
53 	if (cm1.member != 0)
54 		/* In a function call, const members can be assigned. */
55 		take_const_member(cm1);
56 
57 	struct {
58 		const_member member;
59 	} cm2 = {
60 	    /* In a nested initialization, const members can be assigned. */
61 	    cm1,
62 	};
63 	if (cm2.member.member != 0) {
64 	}
65 
66 	/* In a return statement, const members can be assigned. */
67 	return cm1;
68 }
69