Module Name: src Committed By: rillig Date: Fri Jun 24 20:16:21 UTC 2022
Modified Files: src/tests/usr.bin/xlint/lint1: msg_247.c src/usr.bin/xlint/lint1: tree.c Log Message: lint: do not warn about pointer cast between sockaddr variants To generate a diff of this commit: cvs rdiff -u -r1.21 -r1.22 src/tests/usr.bin/xlint/lint1/msg_247.c cvs rdiff -u -r1.460 -r1.461 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/tests/usr.bin/xlint/lint1/msg_247.c diff -u src/tests/usr.bin/xlint/lint1/msg_247.c:1.21 src/tests/usr.bin/xlint/lint1/msg_247.c:1.22 --- src/tests/usr.bin/xlint/lint1/msg_247.c:1.21 Fri Jun 24 20:02:58 2022 +++ src/tests/usr.bin/xlint/lint1/msg_247.c Fri Jun 24 20:16:21 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: msg_247.c,v 1.21 2022/06/24 20:02:58 rillig Exp $ */ +/* $NetBSD: msg_247.c,v 1.22 2022/06/24 20:16:21 rillig Exp $ */ # 3 "msg_247.c" // Test for message: pointer cast from '%s' to '%s' may be troublesome [247] @@ -14,13 +14,14 @@ struct Other { int id; }; -void +PDisplay example(struct Other *arg) { - PDisplay display; - /* - * XXX: The target type is reported as 'struct <unnamed>'. In cases + * Before tree.c 1.461 from 2022-06-24, lint warned about the cast + * between the structs. + * + * XXX: The target type was reported as 'struct <unnamed>'. In cases * like these, it would be helpful to print at least the type name * of the pointer. This type name though is discarded immediately * in the grammar rule 'typespec: T_TYPENAME'. @@ -28,8 +29,7 @@ example(struct Other *arg) * with no hint at all that there is a typedef for a pointer to the * struct. */ - /* expect+1: warning: pointer cast from 'pointer to struct Other' to 'pointer to struct <unnamed>' may be troublesome [247] */ - display = (PDisplay)arg; + return (PDisplay)arg; } /* @@ -249,21 +249,26 @@ struct sockaddr_in6 { uint32_t sin6_scope_id; }; +/* + * Before tree.c 1.461 from 2022-06-24, lint warned about the cast between the + * sockaddr variants. Since then, lint allows casts between pointers to + * structs if the initial members have compatible types and either of the + * struct types continues with a byte array. + */ void * cast_between_sockaddr_variants(void *ptr) { - /* expect+1: warning: pointer cast from 'pointer to struct sockaddr' to 'pointer to struct sockaddr_in' may be troublesome [247] */ void *t1 = (struct sockaddr_in *)(struct sockaddr *)ptr; - - /* expect+1: warning: pointer cast from 'pointer to struct sockaddr_in' to 'pointer to struct sockaddr' may be troublesome [247] */ void *t2 = (struct sockaddr *)(struct sockaddr_in *)t1; - - /* expect+1: warning: pointer cast from 'pointer to struct sockaddr' to 'pointer to struct sockaddr_in6' may be troublesome [247] */ void *t3 = (struct sockaddr_in6 *)(struct sockaddr *)t2; - - /* expect+1: warning: pointer cast from 'pointer to struct sockaddr_in6' to 'pointer to struct sockaddr' may be troublesome [247] */ void *t4 = (struct sockaddr *)(struct sockaddr_in6 *)t3; - return t4; + /* expect+1: warning: pointer cast from 'pointer to struct sockaddr_in6' to 'pointer to struct sockaddr_in' may be troublesome [247] */ + void *t5 = (struct sockaddr_in *)(struct sockaddr_in6 *)t4; + + /* expect+1: warning: pointer cast from 'pointer to struct sockaddr_in' to 'pointer to struct sockaddr_in6' may be troublesome [247] */ + void *t6 = (struct sockaddr_in6 *)(struct sockaddr_in *)t5; + + return t6; } Index: src/usr.bin/xlint/lint1/tree.c diff -u src/usr.bin/xlint/lint1/tree.c:1.460 src/usr.bin/xlint/lint1/tree.c:1.461 --- src/usr.bin/xlint/lint1/tree.c:1.460 Fri Jun 24 19:27:43 2022 +++ src/usr.bin/xlint/lint1/tree.c Fri Jun 24 20:16:21 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: tree.c,v 1.460 2022/06/24 19:27:43 rillig Exp $ */ +/* $NetBSD: tree.c,v 1.461 2022/06/24 20:16:21 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.460 2022/06/24 19:27:43 rillig Exp $"); +__RCSID("$NetBSD: tree.c,v 1.461 2022/06/24 20:16:21 rillig Exp $"); #endif #include <float.h> @@ -2491,6 +2491,14 @@ check_pointer_integer_conversion(op_t op } static bool +is_byte_array(const type_t *tp) +{ + + return tp->t_tspec == ARRAY && + (tp->t_subt->t_tspec == CHAR || tp->t_subt->t_tspec == UCHAR); +} + +static bool should_warn_about_pointer_cast(const type_t *nstp, tspec_t nst, const type_t *ostp, tspec_t ost) { @@ -2512,6 +2520,21 @@ should_warn_about_pointer_cast(const typ if (ost == CHAR || ost == UCHAR) return false; /* for the sake of traditional C code */ + /* Allow cast between pointers to sockaddr variants. */ + if (nst == STRUCT && ost == STRUCT) { + const sym_t *nmem = nstp->t_str->sou_first_member; + const sym_t *omem = ostp->t_str->sou_first_member; + while (nmem != NULL && omem != NULL && + eqtype(nmem->s_type, omem->s_type, true, false, NULL)) + nmem = nmem->s_next, omem = omem->s_next; + if (nmem != NULL && is_byte_array(nmem->s_type)) + return false; + if (omem != NULL && is_byte_array(omem->s_type)) + return false; + if (nmem == NULL && omem == NULL) + return false; + } + if (is_struct_or_union(nst) && nstp->t_str != ostp->t_str) return true;