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