xref: /netbsd-src/tests/usr.bin/xlint/lint1/msg_171.c (revision e6298b924c5ba98f3a22919b56dab04a87cdbb1c)
1 /*	$NetBSD: msg_171.c,v 1.9 2023/07/07 19:45:22 rillig Exp $	*/
2 # 3 "msg_171.c"
3 
4 // Test for message: cannot assign to '%s' from '%s' [171]
5 
6 /* lint1-extra-flags: -X 351 */
7 
8 struct s {
9 	int member;
10 };
11 
12 /*ARGSUSED*/
13 void
example(int i,void * vp,struct s * s)14 example(int i, void *vp, struct s *s)
15 {
16 	/* expect+1: error: cannot assign to 'int' from 'struct s' [171] */
17 	i = *s;
18 	/* expect+1: error: cannot assign to 'struct s' from 'int' [171] */
19 	*s = i;
20 
21 	/* expect+1: error: cannot assign to 'pointer to void' from 'struct s' [171] */
22 	vp = *s;
23 	/* expect+1: error: cannot assign to 'struct s' from 'pointer to void' [171] */
24 	*s = vp;
25 }
26 
27 /*
28  * C99 6.5.2.5 says that a compound literal evaluates to an unnamed object
29  * with automatic storage duration, like any normal named object.  It is an
30  * lvalue, which means that it is possible to take the address of the object.
31  * Seen in external/mpl/bind/dist/lib/dns/rbtdb.c, update_rrsetstats.
32  *
33  * Before init.c 1.111 from 2021-03-23, lint could not handle these nested
34  * initializations (the outer one for the variable 'p', the inner one for the
35  * compound literal) and wrongly complained about a type mismatch between
36  * 'struct point' and 'pointer to struct point'.
37  */
38 void
pointer_to_compound_literal(void)39 pointer_to_compound_literal(void)
40 {
41 	struct point {
42 		int x;
43 		int y;
44 	};
45 	struct point *p = &(struct point){
46 		12, 5,
47 	};
48 
49 	/*
50 	 * A sizeof expression is another way to create nested
51 	 * initializations.
52 	 */
53 	struct point p2 = {
54 		(int)sizeof(struct point){
55 			(int)sizeof(struct point){
56 				(int)sizeof(struct point){
57 					(int)sizeof(struct point){
58 						0,
59 						0,
60 					},
61 					0,
62 				},
63 				0,
64 			},
65 			0,
66 		},
67 		0,
68 	};
69 }
70