xref: /netbsd-src/tests/usr.bin/xlint/lint1/gcc_attribute_aligned.c (revision d69057212d2ebf16ef2f8e0d47e3dda21d3f2a3c)
1 /*	$NetBSD: gcc_attribute_aligned.c,v 1.8 2024/05/01 10:30:56 rillig Exp $	*/
2 # 3 "gcc_attribute_aligned.c"
3 
4 /*
5  * Test size computations on aligned and packed structs.
6  */
7 
8 /* lint1-extra-flags: -X 351 */
9 
10 typedef unsigned short uint16_t;
11 typedef unsigned int uint32_t;
12 typedef unsigned long long uint64_t;
13 
14 /* from sys/arch/x86/include/cpu_extended_state.h */
15 
16 union fp_addr {
17 	uint64_t fa_64;
18 	struct {
19 		uint32_t fa_off;
20 		uint16_t fa_seg;
21 		uint16_t fa_opcode;
22 	} fa_32;
23 } __attribute__((packed)) __attribute__((aligned(4)));
24 
25 /* Each variant of the union has size 8. */
26 /* expect+1: error: negative array dimension (-8) [20] */
27 typedef int sizeof_fp_addr[-(int)sizeof(union fp_addr)];
28 
29 struct fpacc87 {
30 	uint64_t f87_mantissa;
31 	uint16_t f87_exp_sign;
32 } __attribute__((packed)) __attribute__((aligned(2)));
33 
34 /*
35  * Due to the 'packed', the uint64_t does not need to be aligned on an 8-byte
36  * boundary, which allows the struct to have the minimal required size of 10.
37  */
38 /* expect+1: error: negative array dimension (-10) [20] */
39 typedef int sizeof_fpacc87[-(int)sizeof(struct fpacc87)];
40 
41 struct save87 {
42 	uint16_t s87_cw __attribute__((aligned(4)));
43 	uint16_t s87_sw __attribute__((aligned(4)));
44 	uint16_t s87_tw __attribute__((aligned(4)));
45 	union fp_addr s87_ip;
46 	union fp_addr s87_dp;
47 	struct fpacc87 s87_ac[8];
48 };
49 
50 /* @4 2 + @4 2 + @4 2 + @4 8 + @4 8 + @2 (8 * 10) == 108 */
51 /* expect+1: error: negative array dimension (-108) [20] */
52 typedef int sizeof_save87[-(int)sizeof(struct save87)];
53 
54 
55 void
aligned_struct_member(void)56 aligned_struct_member(void)
57 {
58 	struct aligned {
59 		int first;
60 		int second __attribute__((__aligned__(16)));
61 	};
62 
63 	/*
64 	 * Aligning 'second' to a 16-bytes boundary not only aligns the member
65 	 * inside the structure, it also affects the alignment requirement of
66 	 * the whole structure.  Due to this struct alignment, the size of the
67 	 * structure gets rounded up to 32 instead of using the minimally
68 	 * necessary storage of 20.
69 	 *
70 	 * https://gcc.gnu.org/onlinedocs/gcc/Common-Type-Attributes.html
71 	 */
72 	/* expect+1: error: negative array dimension (-32) [20] */
73 	typedef int ctassert[-(int)sizeof(struct aligned)];
74 }
75 
76 void
alignment_larger_than_size(void)77 alignment_larger_than_size(void)
78 {
79 	struct s {
80 		unsigned u32 __attribute__((__aligned__(32)));
81 	} _Alignas(4096);
82 	/* expect+1: error: negative array dimension (-4096) [20] */
83 	typedef int size[-(int)sizeof(struct s)];
84 }
85