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