Module Name:    src
Committed By:   rillig
Date:           Wed May  1 10:30:56 UTC 2024

Modified Files:
        src/tests/usr.bin/xlint/lint1: gcc_attribute_aligned.c
        src/usr.bin/xlint/lint1: decl.c

Log Message:
lint: fix size of struct with large alignment

Lint now successfully passes all compile-time assertions in the amd64
kernel that deal with struct sizes.


To generate a diff of this commit:
cvs rdiff -u -r1.7 -r1.8 \
    src/tests/usr.bin/xlint/lint1/gcc_attribute_aligned.c
cvs rdiff -u -r1.399 -r1.400 src/usr.bin/xlint/lint1/decl.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/tests/usr.bin/xlint/lint1/gcc_attribute_aligned.c
diff -u src/tests/usr.bin/xlint/lint1/gcc_attribute_aligned.c:1.7 src/tests/usr.bin/xlint/lint1/gcc_attribute_aligned.c:1.8
--- src/tests/usr.bin/xlint/lint1/gcc_attribute_aligned.c:1.7	Wed May  1 07:40:11 2024
+++ src/tests/usr.bin/xlint/lint1/gcc_attribute_aligned.c	Wed May  1 10:30:56 2024
@@ -1,4 +1,4 @@
-/*	$NetBSD: gcc_attribute_aligned.c,v 1.7 2024/05/01 07:40:11 rillig Exp $	*/
+/*	$NetBSD: gcc_attribute_aligned.c,v 1.8 2024/05/01 10:30:56 rillig Exp $	*/
 # 3 "gcc_attribute_aligned.c"
 
 /*
@@ -72,3 +72,13 @@ aligned_struct_member(void)
 	/* 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)];
+}

Index: src/usr.bin/xlint/lint1/decl.c
diff -u src/usr.bin/xlint/lint1/decl.c:1.399 src/usr.bin/xlint/lint1/decl.c:1.400
--- src/usr.bin/xlint/lint1/decl.c:1.399	Wed May  1 07:40:11 2024
+++ src/usr.bin/xlint/lint1/decl.c	Wed May  1 10:30:56 2024
@@ -1,4 +1,4 @@
-/* $NetBSD: decl.c,v 1.399 2024/05/01 07:40:11 rillig Exp $ */
+/* $NetBSD: decl.c,v 1.400 2024/05/01 10:30:56 rillig Exp $ */
 
 /*
  * Copyright (c) 1996 Christopher G. Demetriou.  All Rights Reserved.
@@ -38,7 +38,7 @@
 
 #include <sys/cdefs.h>
 #if defined(__RCSID)
-__RCSID("$NetBSD: decl.c,v 1.399 2024/05/01 07:40:11 rillig Exp $");
+__RCSID("$NetBSD: decl.c,v 1.400 2024/05/01 10:30:56 rillig Exp $");
 #endif
 
 #include <sys/param.h>
@@ -463,6 +463,9 @@ void
 dcs_add_alignas(tnode_t *tn)
 {
 	dcs->d_mem_align_in_bits = to_int_constant(tn, true) * CHAR_SIZE;
+	if (dcs->d_type != NULL && is_struct_or_union(dcs->d_type->t_tspec))
+		dcs->d_type->u.sou->sou_align_in_bits =
+		    dcs->d_mem_align_in_bits;
 }
 
 void
@@ -606,6 +609,7 @@ dcs_begin_type(void)
 	dcs->d_redeclared_symbol = NULL;
 	// keep d_sou_size_in_bits
 	// keep d_sou_align_in_bits
+	dcs->d_mem_align_in_bits = 0;
 	dcs->d_qual = (type_qualifiers) { .tq_const = false };
 	dcs->d_inline = false;
 	dcs->d_multiple_storage_classes = false;
@@ -707,6 +711,8 @@ dcs_merge_declaration_specifiers(void)
 	debug_dcs();
 }
 
+static void dcs_align(unsigned int, unsigned int);
+
 /* Create a type in 'dcs->d_type' from the information gathered in 'dcs'. */
 void
 dcs_end_type(void)
@@ -741,6 +747,14 @@ dcs_end_type(void)
 		dcs->d_type->t_const |= dcs->d_qual.tq_const;
 		dcs->d_type->t_volatile |= dcs->d_qual.tq_volatile;
 	}
+	unsigned align = dcs->d_mem_align_in_bits;
+	if (align > 0 && dcs->d_type->t_tspec == STRUCT) {
+		dcs_align(align, 0);
+		dcs->d_type->u.sou->sou_align_in_bits = align;
+		dcs->d_type->u.sou->sou_size_in_bits =
+		    (dcs->d_type->u.sou->sou_size_in_bits + align - 1)
+		    & -align;
+	}
 
 	debug_dcs();
 	debug_leave();
@@ -814,7 +828,6 @@ alignment_in_bits(const type_t *tp)
 			a = worst_align_in_bits;
 	}
 	lint_assert(a >= CHAR_SIZE);
-	lint_assert(a <= worst_align_in_bits);
 	return a;
 }
 

Reply via email to