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)56aligned_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)77alignment_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