| @@ -1,38 +1,50 @@ | | | @@ -1,38 +1,50 @@ |
1 | /* $NetBSD: msg_115.c,v 1.8 2021/08/14 12:46:24 rillig Exp $ */ | | 1 | /* $NetBSD: msg_115.c,v 1.9 2021/08/16 16:19:47 rillig Exp $ */ |
2 | # 3 "msg_115.c" | | 2 | # 3 "msg_115.c" |
3 | | | 3 | |
4 | // Test for message: %soperand of '%s' must be modifiable lvalue [115] | | 4 | // Test for message: %soperand of '%s' must be modifiable lvalue [115] |
5 | | | 5 | |
6 | void | | 6 | void |
7 | example(const int *const_ptr) | | 7 | example(const int *const_ptr) |
8 | { | | 8 | { |
9 | | | 9 | |
10 | *const_ptr = 3; /* expect: 115 */ | | 10 | *const_ptr = 3; /* expect: 115 */ |
11 | *const_ptr += 1; /* expect: 115 */ | | 11 | *const_ptr += 1; /* expect: 115 */ |
12 | *const_ptr -= 4; /* expect: 115 */ | | 12 | *const_ptr -= 4; /* expect: 115 */ |
13 | *const_ptr *= 1; /* expect: 115 */ | | 13 | *const_ptr *= 1; /* expect: 115 */ |
14 | *const_ptr /= 5; /* expect: 115 */ | | 14 | *const_ptr /= 5; /* expect: 115 */ |
15 | *const_ptr %= 9; /* expect: 115 */ | | 15 | *const_ptr %= 9; /* expect: 115 */ |
16 | (*const_ptr)++; /* expect: 115 */ | | 16 | (*const_ptr)++; /* expect: 115 */ |
| | | 17 | |
| | | 18 | /* In the next example, the left operand is not an lvalue at all. */ |
| | | 19 | /* expect+1: error: left operand of '=' must be lvalue [114] */ |
| | | 20 | (const_ptr + 3) = const_ptr; |
17 | } | | 21 | } |
18 | | | 22 | |
19 | typedef struct { | | 23 | typedef struct { |
20 | int const member; | | 24 | int const member; |
21 | } const_member; | | 25 | } const_member; |
22 | | | 26 | |
23 | void take_const_member(const_member); | | 27 | void take_const_member(const_member); |
24 | | | 28 | |
25 | /* see typeok_assign, has_constant_member */ | | 29 | /* |
| | | 30 | * Before init.c 1.208 from 2021-08-14 and decl.c 1.221 from 2021-08-10, |
| | | 31 | * lint issued a wrong "warning: left operand of '%s' must be modifiable |
| | | 32 | * lvalue", even in cases where the left operand was being initialized |
| | | 33 | * instead of overwritten. |
| | | 34 | * |
| | | 35 | * See initialization_expr_using_op, typeok_assign, has_constant_member. |
| | | 36 | * See C99 6.2.5p25. |
| | | 37 | */ |
26 | const_member | | 38 | const_member |
27 | initialize_const_struct_member(void) | | 39 | initialize_const_struct_member(void) |
28 | { | | 40 | { |
29 | /* In a simple initialization, const members can be assigned. */ | | 41 | /* In a simple initialization, const members can be assigned. */ |
30 | const_member cm1 = (const_member) { 12345 }; | | 42 | const_member cm1 = (const_member) { 12345 }; |
31 | | | 43 | |
32 | if (cm1.member != 0) | | 44 | if (cm1.member != 0) |
33 | /* In a function call, const members can be assigned. */ | | 45 | /* In a function call, const members can be assigned. */ |
34 | take_const_member(cm1); | | 46 | take_const_member(cm1); |
35 | | | 47 | |
36 | struct { | | 48 | struct { |
37 | const_member member; | | 49 | const_member member; |
38 | } cm2 = { | | 50 | } cm2 = { |