Module Name:    src
Committed By:   rillig
Date:           Fri Jun 24 20:44:53 UTC 2022

Modified Files:
        src/tests/usr.bin/xlint/lint1: msg_247.c
        src/usr.bin/xlint/lint1: tree.c

Log Message:
lint: allow pointer cast between compatible structs

Lint already allowed pointer casts from 'struct counter' to 'struct
counter_impl'.  Now it also allows the other direction.


To generate a diff of this commit:
cvs rdiff -u -r1.23 -r1.24 src/tests/usr.bin/xlint/lint1/msg_247.c
cvs rdiff -u -r1.461 -r1.462 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.23 src/tests/usr.bin/xlint/lint1/msg_247.c:1.24
--- src/tests/usr.bin/xlint/lint1/msg_247.c:1.23	Fri Jun 24 20:32:12 2022
+++ src/tests/usr.bin/xlint/lint1/msg_247.c	Fri Jun 24 20:44:53 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: msg_247.c,v 1.23 2022/06/24 20:32:12 rillig Exp $	*/
+/*	$NetBSD: msg_247.c,v 1.24 2022/06/24 20:44:53 rillig Exp $	*/
 # 3 "msg_247.c"
 
 // Test for message: pointer cast from '%s' to '%s' may be troublesome [247]
@@ -117,7 +117,7 @@ counter_new_cast(void)
 	struct counter_impl *impl = allocate();
 	impl->public_part.count = 12345;
 	impl->saved_count = 12346;
-	/* expect+1: warning: pointer cast from 'pointer to struct counter_impl' to 'pointer to struct counter' may be troublesome [247] */
+	/* Before tree.c 1.462 from 2022-06-24, lint warned about this cast. */
 	return (struct counter *)impl;
 }
 
@@ -296,9 +296,9 @@ typedef struct ctl_named_node_s {
 } ctl_named_node_t;
 
 void *
-cast_between_initial_struct(void *ptr)
+cast_between_first_member_struct(void *ptr)
 {
-	/* expect+1: warning: pointer cast from 'pointer to struct ctl_named_node_s' to 'pointer to struct ctl_node_s' may be troublesome [247] */
+	/* Before tree.c 1.462 from 2022-06-24, lint warned about this cast. */
 	void *t1 = (ctl_node_t *)(ctl_named_node_t *)ptr;
 
 	void *t2 = (ctl_named_node_t *)(ctl_node_t *)ptr;

Index: src/usr.bin/xlint/lint1/tree.c
diff -u src/usr.bin/xlint/lint1/tree.c:1.461 src/usr.bin/xlint/lint1/tree.c:1.462
--- src/usr.bin/xlint/lint1/tree.c:1.461	Fri Jun 24 20:16:21 2022
+++ src/usr.bin/xlint/lint1/tree.c	Fri Jun 24 20:44:53 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: tree.c,v 1.461 2022/06/24 20:16:21 rillig Exp $	*/
+/*	$NetBSD: tree.c,v 1.462 2022/06/24 20:44:53 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.461 2022/06/24 20:16:21 rillig Exp $");
+__RCSID("$NetBSD: tree.c,v 1.462 2022/06/24 20:44:53 rillig Exp $");
 #endif
 
 #include <float.h>
@@ -2491,6 +2491,15 @@ check_pointer_integer_conversion(op_t op
 }
 
 static bool
+struct_starts_with(const type_t *struct_tp, const type_t *member_tp)
+{
+
+	return struct_tp->t_str->sou_first_member != NULL &&
+	       eqtype(struct_tp->t_str->sou_first_member->s_type, member_tp,
+		   true, false, NULL);
+}
+
+static bool
 is_byte_array(const type_t *tp)
 {
 
@@ -2502,14 +2511,10 @@ static bool
 should_warn_about_pointer_cast(const type_t *nstp, tspec_t nst,
 			       const type_t *ostp, tspec_t ost)
 {
-	/*
-	 * Casting a pointer to 'struct S' to a pointer to another struct that
-	 * has 'struct S' as its first member is ok, see msg_247.c, 'struct
-	 * counter'.
-	 */
+
 	if (nst == STRUCT && ost == STRUCT &&
-	    nstp->t_str->sou_first_member != NULL &&
-	    nstp->t_str->sou_first_member->s_type == ostp)
+	    (struct_starts_with(nstp, ostp) ||
+	     struct_starts_with(ostp, nstp)))
 		return false;
 
 	if (is_incomplete(nstp) || is_incomplete(ostp))

Reply via email to