xref: /netbsd-src/tests/usr.bin/xlint/lint1/msg_115.c (revision b2baa50111d645353fa30b4deab0f79d93650c8c)
1*b2baa501Srillig /*	$NetBSD: msg_115.c,v 1.11 2023/03/28 14:44:34 rillig Exp $	*/
2a0a15c14Srillig # 3 "msg_115.c"
3a0a15c14Srillig 
4a0a15c14Srillig // Test for message: %soperand of '%s' must be modifiable lvalue [115]
5a0a15c14Srillig 
6*b2baa501Srillig /* lint1-extra-flags: -X 351 */
7*b2baa501Srillig 
8af03d2a0Srillig void
example(const int * const_ptr)9af03d2a0Srillig example(const int *const_ptr)
10af03d2a0Srillig {
11af03d2a0Srillig 
1265e5c21bSrillig 	/* expect+1: warning: left operand of '=' must be modifiable lvalue [115] */
1365e5c21bSrillig 	*const_ptr = 3;
1465e5c21bSrillig 	/* expect+1: warning: left operand of '+=' must be modifiable lvalue [115] */
1565e5c21bSrillig 	*const_ptr += 1;
1665e5c21bSrillig 	/* expect+1: warning: left operand of '-=' must be modifiable lvalue [115] */
1765e5c21bSrillig 	*const_ptr -= 4;
1865e5c21bSrillig 	/* expect+1: warning: left operand of '*=' must be modifiable lvalue [115] */
1965e5c21bSrillig 	*const_ptr *= 1;
2065e5c21bSrillig 	/* expect+1: warning: left operand of '/=' must be modifiable lvalue [115] */
2165e5c21bSrillig 	*const_ptr /= 5;
2265e5c21bSrillig 	/* expect+1: warning: left operand of '%=' must be modifiable lvalue [115] */
2365e5c21bSrillig 	*const_ptr %= 9;
2465e5c21bSrillig 	/* expect+1: warning: operand of 'x++' must be modifiable lvalue [115] */
2565e5c21bSrillig 	(*const_ptr)++;
261890122fSrillig 
271890122fSrillig 	/* In the next example, the left operand is not an lvalue at all. */
281890122fSrillig 	/* expect+1: error: left operand of '=' must be lvalue [114] */
291890122fSrillig 	(const_ptr + 3) = const_ptr;
30af03d2a0Srillig }
31fe7cbecdSrillig 
3236db97e5Srillig typedef struct {
3336db97e5Srillig 	int const member;
3436db97e5Srillig } const_member;
3536db97e5Srillig 
3636db97e5Srillig void take_const_member(const_member);
3736db97e5Srillig 
381890122fSrillig /*
391890122fSrillig  * Before init.c 1.208 from 2021-08-14 and decl.c 1.221 from 2021-08-10,
401890122fSrillig  * lint issued a wrong "warning: left operand of '%s' must be modifiable
411890122fSrillig  * lvalue", even in cases where the left operand was being initialized
421890122fSrillig  * instead of overwritten.
431890122fSrillig  *
441890122fSrillig  * See initialization_expr_using_op, typeok_assign, has_constant_member.
451890122fSrillig  * See C99 6.2.5p25.
461890122fSrillig  */
4736db97e5Srillig const_member
initialize_const_struct_member(void)48fe7cbecdSrillig initialize_const_struct_member(void)
49fe7cbecdSrillig {
50c8a8302dSrillig 	/* In a simple initialization, const members can be assigned. */
5136db97e5Srillig 	const_member cm1 = (const_member) { 12345 };
52c8a8302dSrillig 
5336db97e5Srillig 	if (cm1.member != 0)
5436ba9804Srillig 		/* In a function call, const members can be assigned. */
5536db97e5Srillig 		take_const_member(cm1);
56fe7cbecdSrillig 
5736db97e5Srillig 	struct {
5836db97e5Srillig 		const_member member;
5936db97e5Srillig 	} cm2 = {
60c8a8302dSrillig 	    /* In a nested initialization, const members can be assigned. */
6136db97e5Srillig 	    cm1,
6236db97e5Srillig 	};
6336db97e5Srillig 	if (cm2.member.member != 0) {
6436db97e5Srillig 	}
6536db97e5Srillig 
6636ba9804Srillig 	/* In a return statement, const members can be assigned. */
6736db97e5Srillig 	return cm1;
68fe7cbecdSrillig }
69