xref: /netbsd-src/tests/usr.bin/xlint/lint1/d_alignof.c (revision e6298b924c5ba98f3a22919b56dab04a87cdbb1c)
1 /*	$NetBSD: d_alignof.c,v 1.12 2023/07/07 19:45:22 rillig Exp $	*/
2 # 3 "d_alignof.c"
3 
4 /* https://gcc.gnu.org/onlinedocs/gcc/Alignment.html */
5 
6 /* lint1-extra-flags: -X 351 */
7 
8 unsigned long
leading_and_trailing_alignof_type(void)9 leading_and_trailing_alignof_type(void)
10 {
11 	return __alignof__(short);
12 }
13 
14 unsigned long
leading_alignof_type(void)15 leading_alignof_type(void)
16 {
17 	return __alignof(short);
18 }
19 
20 unsigned long
plain_alignof_type(void)21 plain_alignof_type(void)
22 {
23 	/* The plain word 'alignof' is not recognized by GCC. */
24 	/* expect+2: error: function 'alignof' implicitly declared to return int [215] */
25 	/* expect+1: error: syntax error 'short' [249] */
26 	return alignof(short);
27 }
28 /* expect-1: warning: function 'plain_alignof_type' falls off bottom without returning value [217] */
29 
30 unsigned long
leading_and_trailing_alignof_expr(void)31 leading_and_trailing_alignof_expr(void)
32 {
33 	return __alignof__ 3;
34 }
35 
36 unsigned long
leading_alignof_expr(void)37 leading_alignof_expr(void)
38 {
39 	return __alignof 3;
40 }
41 
42 unsigned long
plain_alignof_expr(void)43 plain_alignof_expr(void)
44 {
45 	/* The plain word 'alignof' is not recognized by GCC. */
46 	/* expect+2: error: 'alignof' undefined [99] */
47 	/* expect+1: error: syntax error '3' [249] */
48 	return alignof 3;
49 }
50 /* expect-1: warning: function 'plain_alignof_expr' falls off bottom without returning value [217] */
51 
52 
53 /*
54  * As with 'sizeof', the keyword '__alignof__' doesn't require parentheses
55  * when followed by an expression.  This allows for the seemingly strange
56  * '->' after the parentheses, which in fact is perfectly fine.
57  *
58  * The NetBSD style guide says "We parenthesize sizeof expressions", even
59  * though it is misleading in edge cases like this.  The GCC manual says that
60  * '__alignof__' and 'sizeof' are syntactically the same, therefore the same
61  * reasoning applies to '__alignof__'.
62  */
63 unsigned long
alignof_pointer_to_member(void)64 alignof_pointer_to_member(void)
65 {
66 	struct s {
67 		unsigned long member;
68 	} var = { 0 }, *ptr = &var;
69 
70 	return __alignof__(ptr)->member + ptr->member;
71 }
72 
73 void
alignof_variants(void)74 alignof_variants(void)
75 {
76 	/* expect+1: error: negative array dimension (-4) [20] */
77 	typedef int array_int[-(int)__alignof(int[3])];
78 
79 	/* expect+1: error: negative array dimension (-8) [20] */
80 	typedef int array_double[-(int)__alignof(double[3])];
81 
82 	/* expect+1: error: cannot take size/alignment of function type 'function(int) returning int' [144] */
83 	typedef int func[-(int)__alignof(int(int))];
84 
85 	struct int_double {
86 		int i;
87 		double d;
88 	};
89 	/* expect+1: error: negative array dimension (-8) [20] */
90 	typedef int struct_int_double[-(int)__alignof(struct int_double)];
91 
92 	struct chars {
93 		char name[20];
94 	};
95 	/* expect+1: error: negative array dimension (-1) [20] */
96 	typedef int struct_chars[-(int)__alignof(struct chars)];
97 
98 	/* expect+1: warning: struct 'incomplete_struct' never defined [233] */
99 	struct incomplete_struct;
100 	/* expect+1: error: cannot take size/alignment of incomplete type [143] */
101 	typedef int incomplete_struct[-(int)__alignof(struct incomplete_struct)];
102 
103 	/* expect+1: warning: union 'incomplete_union' never defined [234] */
104 	union incomplete_union;
105 	/* expect+1: error: cannot take size/alignment of incomplete type [143] */
106 	typedef int incomplete_union[-(int)__alignof(union incomplete_union)];
107 
108 	/* expect+1: warning: enum 'incomplete_enum' never defined [235] */
109 	enum incomplete_enum;
110 	/* expect+1: error: cannot take size/alignment of incomplete type [143] */
111 	typedef int incomplete_enum[-(int)__alignof(enum incomplete_enum)];
112 
113 	/* expect+1: error: cannot take size/alignment of incomplete type [143] */
114 	typedef int incomplete_array[-(int)__alignof(int[])];
115 
116 	struct bit_fields {
117 		_Bool bit_field:1;
118 	};
119 	/*
120 	 * FIXME: This is not an attempt to initialize the typedef, it's the
121 	 * initialization of a nested expression.
122 	 */
123 	/* expect+2: error: cannot initialize typedef '00000000_tmp' [25] */
124 	/* expect+1: error: cannot take size/alignment of bit-field [145] */
125 	typedef int bit_field_1[-(int)__alignof((struct bit_fields){0}.bit_field)];
126 
127 	struct bit_fields bit_fields;
128 	/* expect+1: error: cannot take size/alignment of bit-field [145] */
129 	typedef int bit_field_2[-(int)__alignof(bit_fields.bit_field)];
130 
131 	/* expect+1: error: cannot take size/alignment of void [146] */
132 	typedef int plain_void[-(int)__alignof(void)];
133 }
134