Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/usr.bin/xlint/lint1 lint: fix computation of bit-field width
details: https://anonhg.NetBSD.org/src/rev/45f343f193db
branches: trunk
changeset: 377187:45f343f193db
user: rillig <rillig%NetBSD.org@localhost>
date: Fri Jun 30 15:19:09 2023 +0000
description:
lint: fix computation of bit-field width
When bit-fields in packed structs were added on 2009-10-02, lint assumed
that they would only use 'signed int' or 'unsigned int' as storage unit,
even though C99 also allows _Bool.
The cleanup commit for decl.c 1.225 from 2021-08-28 accidentally changed
the rounding mode for bit-field storage units from round-up to
round-down.
diffstat:
tests/usr.bin/xlint/lint1/expr_sizeof.c | 4 +-
tests/usr.bin/xlint/lint1/msg_065.c | 4 +-
usr.bin/xlint/lint1/decl.c | 34 ++++++++++++++++++--------------
3 files changed, 23 insertions(+), 19 deletions(-)
diffs (127 lines):
diff -r e92cd2195cc0 -r 45f343f193db tests/usr.bin/xlint/lint1/expr_sizeof.c
--- a/tests/usr.bin/xlint/lint1/expr_sizeof.c Fri Jun 30 14:39:23 2023 +0000
+++ b/tests/usr.bin/xlint/lint1/expr_sizeof.c Fri Jun 30 15:19:09 2023 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: expr_sizeof.c,v 1.9 2023/06/30 09:21:52 rillig Exp $ */
+/* $NetBSD: expr_sizeof.c,v 1.10 2023/06/30 15:19:09 rillig Exp $ */
# 3 "expr_sizeof.c"
/*
@@ -92,7 +92,7 @@ bit_fields(void)
_Bool flag2:1;
};
} anonymous_flags;
- /* FIXME: sizeof must be 1, not 0. */
+ /* expect+1: error: negative array dimension (-1) [20] */
typedef int sizeof_anonymous_flags[-(int)sizeof(anonymous_flags)];
struct {
diff -r e92cd2195cc0 -r 45f343f193db tests/usr.bin/xlint/lint1/msg_065.c
--- a/tests/usr.bin/xlint/lint1/msg_065.c Fri Jun 30 14:39:23 2023 +0000
+++ b/tests/usr.bin/xlint/lint1/msg_065.c Fri Jun 30 15:19:09 2023 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: msg_065.c,v 1.4 2022/06/22 19:23:18 rillig Exp $ */
+/* $NetBSD: msg_065.c,v 1.5 2023/06/30 15:19:09 rillig Exp $ */
# 3 "msg_065.c"
// Test for message: '%s' has no named members [65]
@@ -7,7 +7,7 @@ struct ok {
int member;
};
-/* XXX: should generate a warning as well. */
+/* Don't warn about completely empty structs, which are a GCC extension. */
struct empty {
};
diff -r e92cd2195cc0 -r 45f343f193db usr.bin/xlint/lint1/decl.c
--- a/usr.bin/xlint/lint1/decl.c Fri Jun 30 14:39:23 2023 +0000
+++ b/usr.bin/xlint/lint1/decl.c Fri Jun 30 15:19:09 2023 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: decl.c,v 1.325 2023/06/30 14:39:23 rillig Exp $ */
+/* $NetBSD: decl.c,v 1.326 2023/06/30 15:19:09 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.325 2023/06/30 14:39:23 rillig Exp $");
+__RCSID("$NetBSD: decl.c,v 1.326 2023/06/30 15:19:09 rillig Exp $");
#endif
#include <sys/param.h>
@@ -456,18 +456,20 @@ set_first_typedef(type_t *tp, sym_t *sym
}
static unsigned int
-bit_field_width(sym_t **mem)
+bit_field_width(sym_t **mem, bool *named)
{
- unsigned int width = (*mem)->s_type->t_bit_field_width;
+ unsigned int width = 0;
+ unsigned int align = 0;
while (*mem != NULL && (*mem)->s_type->t_bitfield) {
+ 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);
+ if (mem_align > align)
+ align = mem_align;
*mem = (*mem)->s_next;
}
-
- // XXX: Why INT_SIZE? C99 6.7.2.1p4 allows bit-fields to have type
- // XXX: _Bool or another implementation-defined type.
- // XXX: Why round down instead of up? See expr_sizeof.c, anonymous_flags.
- return width - width % INT_SIZE;
+ return (width + align - 1) & -align;
}
static void
@@ -481,11 +483,12 @@ pack_struct_or_union(type_t *tp)
}
unsigned int bits = 0;
+ bool named = false;
for (sym_t *mem = tp->t_sou->sou_first_member;
mem != NULL; mem = mem->s_next) {
// TODO: Maybe update mem->u.s_member.sm_offset_in_bits.
if (mem->s_type->t_bitfield) {
- bits += bit_field_width(&mem);
+ bits += bit_field_width(&mem, &named);
if (mem == NULL)
break;
}
@@ -1795,24 +1798,25 @@ complete_struct_or_union(sym_t *first_me
c99ism(47, tspec_name(tp->t_tspec));
}
- int n = 0;
+ bool has_named_member = false;
for (sym_t *mem = first_member; mem != NULL; mem = mem->s_next) {
+ if (mem->s_name != unnamed)
+ has_named_member = true;
/* bind anonymous members to the structure */
if (mem->u.s_member.sm_sou_type == NULL) {
mem->u.s_member.sm_sou_type = sp;
if (mem->s_type->t_bitfield) {
- sp->sou_size_in_bits += bit_field_width(&mem);
+ sp->sou_size_in_bits +=
+ bit_field_width(&mem, &has_named_member);
if (mem == NULL)
break;
}
sp->sou_size_in_bits +=
type_size_in_bits(mem->s_type);
}
- if (mem->s_name != unnamed)
- n++;
}
- if (n == 0 && sp->sou_size_in_bits != 0) {
+ if (!has_named_member && sp->sou_size_in_bits != 0) {
/* '%s' has no named members */
warning(65, type_name(tp));
}
Home |
Main Index |
Thread Index |
Old Index