summaryrefslogtreecommitdiff
path: root/usr.bin/xlint/lint1/tree.c
diff options
context:
space:
mode:
authorrillig <rillig@NetBSD.org>2023-07-08 16:13:00 +0000
committerrillig <rillig@NetBSD.org>2023-07-08 16:13:00 +0000
commit9299a7c5194512b0d5ea06c7b286d4bae6640791 (patch)
treec91e393a4af29d255b4af29197c80f1202c0f6f2 /usr.bin/xlint/lint1/tree.c
parent96e65dba728fddd2104244f530812358469a0896 (diff)
lint: warn about pointer casts between different kinds of types
Pointer casts from an integer type to a floating-point type and vice versa get a 'maybe troublesome' warning now. The previous assumption that all types of the same bit-size are convertible may have been valid from a technical point of view, but still such code should get more attention. The rules for struct and union types could be made more fine-grained later, if the need arises. To suppress this warning, it's always possible to cast to an intermediate 'void *'.
Diffstat (limited to 'usr.bin/xlint/lint1/tree.c')
-rw-r--r--usr.bin/xlint/lint1/tree.c21
1 files changed, 13 insertions, 8 deletions
diff --git a/usr.bin/xlint/lint1/tree.c b/usr.bin/xlint/lint1/tree.c
index 9da4e6c1e9f..d6109cdc165 100644
--- a/usr.bin/xlint/lint1/tree.c
+++ b/usr.bin/xlint/lint1/tree.c
@@ -1,4 +1,4 @@
-/* $NetBSD: tree.c,v 1.553 2023/07/08 15:26:25 rillig Exp $ */
+/* $NetBSD: tree.c,v 1.554 2023/07/08 16:13:00 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.553 2023/07/08 15:26:25 rillig Exp $");
+__RCSID("$NetBSD: tree.c,v 1.554 2023/07/08 16:13:00 rillig Exp $");
#endif
#include <float.h>
@@ -100,9 +100,11 @@ width_in_bits(const type_t *tp)
static int
portable_rank_cmp(tspec_t t1, tspec_t t2) {
- unsigned int r1 = type_properties(t1)->tt_rank;
- unsigned int r2 = type_properties(t2)->tt_rank;
- return (int)r1 - (int)r2;
+ const ttab_t *p1 = type_properties(t1), *p2 = type_properties(t2);
+ lint_assert(p1->tt_rank_kind == p2->tt_rank_kind);
+ lint_assert(p1->tt_rank_value > 0);
+ lint_assert(p2->tt_rank_value > 0);
+ return (int)p1->tt_rank_value - (int)p2->tt_rank_value;
}
static bool
@@ -3541,8 +3543,6 @@ should_warn_about_pointer_cast(const type_t *nstp, tspec_t nst,
/* Allow cast between pointers to sockaddr variants. */
if (nst == STRUCT && ost == STRUCT) {
- debug_type(nstp);
- debug_type(ostp);
const sym_t *nmem = nstp->t_sou->sou_first_member;
const sym_t *omem = ostp->t_sou->sou_first_member;
while (nmem != NULL && omem != NULL &&
@@ -3564,7 +3564,12 @@ should_warn_about_pointer_cast(const type_t *nstp, tspec_t nst,
return false;
}
- if (is_struct_or_union(nst) && nstp->t_sou != ostp->t_sou)
+ if (is_struct_or_union(nst) && is_struct_or_union(ost))
+ return nstp->t_sou != ostp->t_sou;
+
+ enum rank_kind rk1 = type_properties(nst)->tt_rank_kind;
+ enum rank_kind rk2 = type_properties(ost)->tt_rank_kind;
+ if (rk1 != rk2 || rk1 == RK_NONE)
return true;
return portable_rank_cmp(nst, ost) != 0;