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;
 

Reply via email to