Module Name:    src
Committed By:   rillig
Date:           Fri May  3 04:04:18 UTC 2024

Modified Files:
        src/usr.bin/xlint/lint1: cgram.y debug.c decl.c externs1.h lint1.h
            tree.c

Log Message:
lint: measure the alignment in bytes, not bits

While measuring the alignment in bits makes sense when building a struct
type with bit-fields, in all other places it is more confusing than
helpful.

The only visible change is that in debug mode, the format of type sizes
and alignment changed.  Since the size of all complete types is a
multiple of a byte (as defined in the C standard), sizes and alignments
are reported in bytes as well.  Only while a struct is being built, the
type size may include an additional '+x' for the bits of a bit-field.


To generate a diff of this commit:
cvs rdiff -u -r1.494 -r1.495 src/usr.bin/xlint/lint1/cgram.y
cvs rdiff -u -r1.76 -r1.77 src/usr.bin/xlint/lint1/debug.c
cvs rdiff -u -r1.400 -r1.401 src/usr.bin/xlint/lint1/decl.c
cvs rdiff -u -r1.223 -r1.224 src/usr.bin/xlint/lint1/externs1.h \
    src/usr.bin/xlint/lint1/lint1.h
cvs rdiff -u -r1.639 -r1.640 src/usr.bin/xlint/lint1/tree.c

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

Modified files:

Index: src/usr.bin/xlint/lint1/cgram.y
diff -u src/usr.bin/xlint/lint1/cgram.y:1.494 src/usr.bin/xlint/lint1/cgram.y:1.495
--- src/usr.bin/xlint/lint1/cgram.y:1.494	Wed May  1 07:40:11 2024
+++ src/usr.bin/xlint/lint1/cgram.y	Fri May  3 04:04:17 2024
@@ -1,5 +1,5 @@
 %{
-/* $NetBSD: cgram.y,v 1.494 2024/05/01 07:40:11 rillig Exp $ */
+/* $NetBSD: cgram.y,v 1.495 2024/05/03 04:04:17 rillig Exp $ */
 
 /*
  * Copyright (c) 1996 Christopher G. Demetriou.  All Rights Reserved.
@@ -35,7 +35,7 @@
 
 #include <sys/cdefs.h>
 #if defined(__RCSID)
-__RCSID("$NetBSD: cgram.y,v 1.494 2024/05/01 07:40:11 rillig Exp $");
+__RCSID("$NetBSD: cgram.y,v 1.495 2024/05/03 04:04:17 rillig Exp $");
 #endif
 
 #include <limits.h>
@@ -1026,7 +1026,7 @@ struct_or_union:
 		set_sym_kind(SK_TAG);
 		begin_declaration_level($1 == STRUCT ? DLK_STRUCT : DLK_UNION);
 		dcs->d_sou_size_in_bits = 0;
-		dcs->d_sou_align_in_bits = CHAR_SIZE;
+		dcs->d_sou_align = 1;
 		$$ = $1;
 	}
 |	struct_or_union type_attribute

Index: src/usr.bin/xlint/lint1/debug.c
diff -u src/usr.bin/xlint/lint1/debug.c:1.76 src/usr.bin/xlint/lint1/debug.c:1.77
--- src/usr.bin/xlint/lint1/debug.c:1.76	Wed May  1 07:40:11 2024
+++ src/usr.bin/xlint/lint1/debug.c	Fri May  3 04:04:17 2024
@@ -1,4 +1,4 @@
-/* $NetBSD: debug.c,v 1.76 2024/05/01 07:40:11 rillig Exp $ */
+/* $NetBSD: debug.c,v 1.77 2024/05/03 04:04:17 rillig Exp $ */
 
 /*-
  * Copyright (c) 2021 The NetBSD Foundation, Inc.
@@ -35,7 +35,7 @@
 
 #include <sys/cdefs.h>
 #if defined(__RCSID)
-__RCSID("$NetBSD: debug.c,v 1.76 2024/05/01 07:40:11 rillig Exp $");
+__RCSID("$NetBSD: debug.c,v 1.77 2024/05/03 04:04:17 rillig Exp $");
 #endif
 
 #include <stdlib.h>
@@ -155,8 +155,12 @@ debug_type_details(const type_t *tp)
 
 	if (is_struct_or_union(tp->t_tspec)) {
 		debug_indent_inc();
-		debug_step("size %u bits, align %u bits, %s",
-		    tp->u.sou->sou_size_in_bits, tp->u.sou->sou_align_in_bits,
+		unsigned int size_in_bits = tp->u.sou->sou_size_in_bits;
+		debug_printf("size %u", size_in_bits / CHAR_SIZE);
+		if (size_in_bits % CHAR_SIZE > 0)
+			debug_printf("+%u", size_in_bits % CHAR_SIZE);
+		debug_step(", align %u, %s",
+		    tp->u.sou->sou_align,
 		    tp->u.sou->sou_incomplete ? "incomplete" : "complete");
 
 		for (const sym_t *mem = tp->u.sou->sou_first_member;
@@ -458,12 +462,14 @@ debug_decl_level(const decl_level *dl)
 	}
 	if (dl->d_redeclared_symbol != NULL)
 		debug_sym(" redeclared=(", dl->d_redeclared_symbol, ")");
-	if (dl->d_sou_size_in_bits != 0)
-		debug_printf(" size=%u", dl->d_sou_size_in_bits);
-	if (dl->d_sou_align_in_bits != 0)
-		debug_printf(" sou_align=%u", dl->d_sou_align_in_bits);
-	if (dl->d_mem_align_in_bits != 0)
-		debug_printf(" mem_align=%u", dl->d_mem_align_in_bits);
+	if (dl->d_sou_size_in_bits > 0)
+		debug_printf(" size=%u", dl->d_sou_size_in_bits / CHAR_SIZE);
+	if (dl->d_sou_size_in_bits % CHAR_SIZE > 0)
+		debug_printf("+%u", dl->d_sou_size_in_bits % CHAR_SIZE);
+	if (dl->d_sou_align > 0)
+		debug_printf(" sou_align=%u", dl->d_sou_align);
+	if (dl->d_mem_align > 0)
+		debug_printf(" mem_align=%u", dl->d_mem_align);
 
 	debug_word(dl->d_qual.tq_const, "const");
 	debug_word(dl->d_qual.tq_restrict, "restrict");

Index: src/usr.bin/xlint/lint1/decl.c
diff -u src/usr.bin/xlint/lint1/decl.c:1.400 src/usr.bin/xlint/lint1/decl.c:1.401
--- src/usr.bin/xlint/lint1/decl.c:1.400	Wed May  1 10:30:56 2024
+++ src/usr.bin/xlint/lint1/decl.c	Fri May  3 04:04:17 2024
@@ -1,4 +1,4 @@
-/* $NetBSD: decl.c,v 1.400 2024/05/01 10:30:56 rillig Exp $ */
+/* $NetBSD: decl.c,v 1.401 2024/05/03 04:04:17 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.400 2024/05/01 10:30:56 rillig Exp $");
+__RCSID("$NetBSD: decl.c,v 1.401 2024/05/03 04:04:17 rillig Exp $");
 #endif
 
 #include <sys/param.h>
@@ -421,12 +421,13 @@ bit_fields_width(const sym_t **mem, bool
 		if ((*mem)->s_name != unnamed)
 			*named = true;
 		width += (*mem)->s_type->t_bit_field_width;
-		unsigned int mem_align = alignment_in_bits((*mem)->s_type);
+		unsigned mem_align = alignment((*mem)->s_type);
 		if (mem_align > align)
 			align = mem_align;
 		*mem = (*mem)->s_next;
 	}
-	return (width + align - 1) & -align;
+	unsigned align_in_bits = align * CHAR_BIT;
+	return (width + align_in_bits - 1) & -align_in_bits;
 }
 
 static void
@@ -462,10 +463,9 @@ pack_struct_or_union(type_t *tp)
 void
 dcs_add_alignas(tnode_t *tn)
 {
-	dcs->d_mem_align_in_bits = to_int_constant(tn, true) * CHAR_SIZE;
+	dcs->d_mem_align = to_int_constant(tn, true);
 	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;
+		dcs->d_type->u.sou->sou_align = dcs->d_mem_align;
 }
 
 void
@@ -608,8 +608,8 @@ dcs_begin_type(void)
 	dcs->d_type = NULL;
 	dcs->d_redeclared_symbol = NULL;
 	// keep d_sou_size_in_bits
-	// keep d_sou_align_in_bits
-	dcs->d_mem_align_in_bits = 0;
+	// keep d_sou_align
+	dcs->d_mem_align = 0;
 	dcs->d_qual = (type_qualifiers) { .tq_const = false };
 	dcs->d_inline = false;
 	dcs->d_multiple_storage_classes = false;
@@ -747,13 +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;
+	unsigned align = dcs->d_mem_align;
 	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_align = align;
+		unsigned align_in_bits = align * CHAR_SIZE;
 		dcs->d_type->u.sou->sou_size_in_bits =
-		    (dcs->d_type->u.sou->sou_size_in_bits + align - 1)
-		    & -align;
+		    (dcs->d_type->u.sou->sou_size_in_bits + align_in_bits - 1)
+		    & -align_in_bits;
 	}
 
 	debug_dcs();
@@ -807,27 +808,27 @@ length_in_bits(const type_t *tp, const c
 }
 
 unsigned int
-alignment_in_bits(const type_t *tp)
+alignment(const type_t *tp)
 {
 
 	/* Super conservative so that it works for most systems. */
-	unsigned int worst_align_in_bits = 2 * LONG_SIZE;
+	unsigned worst_align = 2 * LONG_SIZE / CHAR_SIZE;
 
 	while (tp->t_tspec == ARRAY)
 		tp = tp->t_subt;
 
 	tspec_t t = tp->t_tspec;
-	unsigned int a;
+	unsigned a;
 	if (is_struct_or_union(t))
-		a = tp->u.sou->sou_align_in_bits;
+		a = tp->u.sou->sou_align;
 	else {
 		lint_assert(t != FUNC);
-		if ((a = size_in_bits(t)) == 0)
-			a = CHAR_SIZE;
-		else if (a > worst_align_in_bits)
-			a = worst_align_in_bits;
+		if ((a = size_in_bits(t) / CHAR_SIZE) == 0)
+			a = 1;
+		else if (a > worst_align)
+			a = worst_align;
 	}
-	lint_assert(a >= CHAR_SIZE);
+	lint_assert(a >= 1);
 	return a;
 }
 
@@ -1021,16 +1022,17 @@ check_bit_field(sym_t *dsym, tspec_t *in
 	}
 }
 
-/* Aligns the next structure element as required. */
+/* Aligns the next structure member as required. */
 static void
 dcs_align(unsigned int member_alignment, unsigned int bit_field_width)
 {
 
-	if (member_alignment > dcs->d_sou_align_in_bits)
-		dcs->d_sou_align_in_bits = member_alignment;
+	if (member_alignment > dcs->d_sou_align)
+		dcs->d_sou_align = member_alignment;
 
-	unsigned int offset = (dcs->d_sou_size_in_bits + member_alignment - 1)
-	    & ~(member_alignment - 1);
+	unsigned align_in_bits = member_alignment * CHAR_SIZE;
+	unsigned offset = (dcs->d_sou_size_in_bits + align_in_bits - 1)
+	    & -align_in_bits;
 	if (bit_field_width == 0
 	    || dcs->d_sou_size_in_bits + bit_field_width > offset)
 		dcs->d_sou_size_in_bits = offset;
@@ -1049,7 +1051,7 @@ dcs_add_member(sym_t *mem)
 	}
 
 	if (mem->s_bitfield) {
-		dcs_align(alignment_in_bits(tp), tp->t_bit_field_width);
+		dcs_align(alignment(tp), tp->t_bit_field_width);
 		// XXX: Why round down?
 		mem->u.s_member.sm_offset_in_bits = dcs->d_sou_size_in_bits
 		    - dcs->d_sou_size_in_bits % size_in_bits(tp->t_tspec);
@@ -1057,9 +1059,9 @@ dcs_add_member(sym_t *mem)
 		    - mem->u.s_member.sm_offset_in_bits;
 		dcs->d_sou_size_in_bits += tp->t_bit_field_width;
 	} else {
-		unsigned int align_in_bits = dcs->d_mem_align_in_bits > 0
-		    ? dcs->d_mem_align_in_bits : alignment_in_bits(tp);
-		dcs_align(align_in_bits, 0);
+		unsigned int align = dcs->d_mem_align > 0
+		    ? dcs->d_mem_align : alignment(tp);
+		dcs_align(align, 0);
 		mem->u.s_member.sm_offset_in_bits = dcs->d_sou_size_in_bits;
 		dcs->d_sou_size_in_bits += type_size_in_bits(tp);
 	}
@@ -1654,7 +1656,7 @@ make_tag_type(sym_t *tag, tspec_t kind, 
 		if (kind != ENUM) {
 			tp->u.sou = block_zero_alloc(sizeof(*tp->u.sou),
 			    "struct_or_union");
-			tp->u.sou->sou_align_in_bits = CHAR_SIZE;
+			tp->u.sou->sou_align = 1;
 			tp->u.sou->sou_tag = tag;
 			tp->u.sou->sou_incomplete = true;
 		} else {
@@ -1692,10 +1694,10 @@ complete_struct_or_union(sym_t *first_me
 	if (tp == NULL)		/* in case of syntax errors */
 		return gettyp(INT);
 
-	dcs_align(dcs->d_sou_align_in_bits, 0);
+	dcs_align(dcs->d_sou_align, 0);
 
 	struct_or_union *sou = tp->u.sou;
-	sou->sou_align_in_bits = dcs->d_sou_align_in_bits;
+	sou->sou_align = dcs->d_sou_align;
 	sou->sou_incomplete = false;
 	sou->sou_first_member = first_member;
 	if (tp->t_packed)

Index: src/usr.bin/xlint/lint1/externs1.h
diff -u src/usr.bin/xlint/lint1/externs1.h:1.223 src/usr.bin/xlint/lint1/externs1.h:1.224
--- src/usr.bin/xlint/lint1/externs1.h:1.223	Wed May  1 07:40:11 2024
+++ src/usr.bin/xlint/lint1/externs1.h	Fri May  3 04:04:18 2024
@@ -1,4 +1,4 @@
-/*	$NetBSD: externs1.h,v 1.223 2024/05/01 07:40:11 rillig Exp $	*/
+/*	$NetBSD: externs1.h,v 1.224 2024/05/03 04:04:18 rillig Exp $	*/
 
 /*
  * Copyright (c) 1994, 1995 Jochen Pohl
@@ -224,7 +224,7 @@ void dcs_set_asm(void);
 void dcs_begin_type(void);
 void dcs_end_type(void);
 int length_in_bits(const type_t *, const char *);
-unsigned int alignment_in_bits(const type_t *);
+unsigned int alignment(const type_t *);
 sym_t *concat_symbols(sym_t *, sym_t *);
 void check_type(sym_t *);
 sym_t *declare_unnamed_member(void);
Index: src/usr.bin/xlint/lint1/lint1.h
diff -u src/usr.bin/xlint/lint1/lint1.h:1.223 src/usr.bin/xlint/lint1/lint1.h:1.224
--- src/usr.bin/xlint/lint1/lint1.h:1.223	Wed May  1 07:40:11 2024
+++ src/usr.bin/xlint/lint1/lint1.h	Fri May  3 04:04:18 2024
@@ -1,4 +1,4 @@
-/* $NetBSD: lint1.h,v 1.223 2024/05/01 07:40:11 rillig Exp $ */
+/* $NetBSD: lint1.h,v 1.224 2024/05/03 04:04:18 rillig Exp $ */
 
 /*
  * Copyright (c) 1996 Christopher G. Demetriou.  All Rights Reserved.
@@ -108,7 +108,7 @@ typedef struct sym sym_t;
  */
 typedef struct {
 	unsigned int sou_size_in_bits;
-	unsigned int sou_align_in_bits;
+	unsigned int sou_align;
 	bool	sou_incomplete:1;
 	sym_t	*sou_first_member;
 	sym_t	*sou_tag;
@@ -340,10 +340,10 @@ typedef struct decl_level {
 	unsigned int d_sou_size_in_bits;	/* size of the structure or
 						 * union being built, without
 						 * trailing padding */
-	unsigned int d_sou_align_in_bits;	/* alignment of the structure
-						 * or union being built */
-	unsigned int d_mem_align_in_bits;	/* alignment of the structure
-						 * or union member */
+	unsigned int d_sou_align;	/* alignment of the structure
+					 * or union being built */
+	unsigned int d_mem_align;	/* alignment of the structure
+					 * or union member */
 	type_qualifiers d_qual;	/* in declaration specifiers */
 	bool	d_inline:1;	/* inline in declaration specifiers */
 	bool	d_multiple_storage_classes:1; /* reported in dcs_end_type */

Index: src/usr.bin/xlint/lint1/tree.c
diff -u src/usr.bin/xlint/lint1/tree.c:1.639 src/usr.bin/xlint/lint1/tree.c:1.640
--- src/usr.bin/xlint/lint1/tree.c:1.639	Wed May  1 17:42:57 2024
+++ src/usr.bin/xlint/lint1/tree.c	Fri May  3 04:04:18 2024
@@ -1,4 +1,4 @@
-/*	$NetBSD: tree.c,v 1.639 2024/05/01 17:42:57 rillig Exp $	*/
+/*	$NetBSD: tree.c,v 1.640 2024/05/03 04:04:18 rillig Exp $	*/
 
 /*
  * Copyright (c) 1994, 1995 Jochen Pohl
@@ -37,7 +37,7 @@
 
 #include <sys/cdefs.h>
 #if defined(__RCSID)
-__RCSID("$NetBSD: tree.c,v 1.639 2024/05/01 17:42:57 rillig Exp $");
+__RCSID("$NetBSD: tree.c,v 1.640 2024/05/03 04:04:18 rillig Exp $");
 #endif
 
 #include <float.h>
@@ -3598,14 +3598,13 @@ convert_pointer_from_pointer(type_t *ntp
 		return;
 	}
 
-	if (hflag && alignment_in_bits(nstp) > alignment_in_bits(ostp) &&
+	if (hflag && alignment(nstp) > alignment(ostp) &&
 	    ost != CHAR && ost != UCHAR &&
 	    !is_incomplete(ostp) &&
 	    !(nst == UNION && union_contains(nstp, ostp))) {
 		/* converting '%s' to '%s' increases alignment ... */
 		warning(135, type_name(otp), type_name(ntp),
-		    alignment_in_bits(ostp) / CHAR_SIZE,
-		    alignment_in_bits(nstp) / CHAR_SIZE);
+		    alignment(ostp), alignment(nstp));
 	}
 
 	if (cflag && should_warn_about_pointer_cast(nstp, nst, ostp, ost)) {
@@ -4083,8 +4082,7 @@ build_alignof(const type_t *tp)
 		error(145);
 		return NULL;
 	}
-	return build_integer_constant(SIZEOF_TSPEC,
-	    (int64_t)alignment_in_bits(tp) / CHAR_SIZE);
+	return build_integer_constant(SIZEOF_TSPEC, (int64_t)alignment(tp));
 }
 
 static tnode_t *

Reply via email to