/* $NetBSD: gcc_attribute_aligned.c,v 1.8 2024/05/01 10:30:56 rillig Exp $ */ # 3 "gcc_attribute_aligned.c" /* * Test size computations on aligned and packed structs. */ /* lint1-extra-flags: -X 351 */ typedef unsigned short uint16_t; typedef unsigned int uint32_t; typedef unsigned long long uint64_t; /* from sys/arch/x86/include/cpu_extended_state.h */ union fp_addr { uint64_t fa_64; struct { uint32_t fa_off; uint16_t fa_seg; uint16_t fa_opcode; } fa_32; } __attribute__((packed)) __attribute__((aligned(4))); /* Each variant of the union has size 8. */ /* expect+1: error: negative array dimension (-8) [20] */ typedef int sizeof_fp_addr[-(int)sizeof(union fp_addr)]; struct fpacc87 { uint64_t f87_mantissa; uint16_t f87_exp_sign; } __attribute__((packed)) __attribute__((aligned(2))); /* * Due to the 'packed', the uint64_t does not need to be aligned on an 8-byte * boundary, which allows the struct to have the minimal required size of 10. */ /* expect+1: error: negative array dimension (-10) [20] */ typedef int sizeof_fpacc87[-(int)sizeof(struct fpacc87)]; struct save87 { uint16_t s87_cw __attribute__((aligned(4))); uint16_t s87_sw __attribute__((aligned(4))); uint16_t s87_tw __attribute__((aligned(4))); union fp_addr s87_ip; union fp_addr s87_dp; struct fpacc87 s87_ac[8]; }; /* @4 2 + @4 2 + @4 2 + @4 8 + @4 8 + @2 (8 * 10) == 108 */ /* expect+1: error: negative array dimension (-108) [20] */ typedef int sizeof_save87[-(int)sizeof(struct save87)]; void aligned_struct_member(void) { struct aligned { int first; int second __attribute__((__aligned__(16))); }; /* * Aligning 'second' to a 16-bytes boundary not only aligns the member * inside the structure, it also affects the alignment requirement of * the whole structure. Due to this struct alignment, the size of the * structure gets rounded up to 32 instead of using the minimally * necessary storage of 20. * * https://gcc.gnu.org/onlinedocs/gcc/Common-Type-Attributes.html */ /* expect+1: error: negative array dimension (-32) [20] */ typedef int ctassert[-(int)sizeof(struct aligned)]; } void alignment_larger_than_size(void) { struct s { unsigned u32 __attribute__((__aligned__(32))); } _Alignas(4096); /* expect+1: error: negative array dimension (-4096) [20] */ typedef int size[-(int)sizeof(struct s)]; }