Module Name:    src
Committed By:   rillig
Date:           Sat Apr 22 17:42:29 UTC 2023

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

Log Message:
lint: don't warn about cast between union and one of its member types

Seen in src/sbin/newfs_udf/udf_core.c for context.anchors.


To generate a diff of this commit:
cvs rdiff -u -r1.28 -r1.29 src/tests/usr.bin/xlint/lint1/msg_247.c
cvs rdiff -u -r1.515 -r1.516 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.28 src/tests/usr.bin/xlint/lint1/msg_247.c:1.29
--- src/tests/usr.bin/xlint/lint1/msg_247.c:1.28	Sat Apr 22 17:30:35 2023
+++ src/tests/usr.bin/xlint/lint1/msg_247.c	Sat Apr 22 17:42:29 2023
@@ -1,4 +1,4 @@
-/*	$NetBSD: msg_247.c,v 1.28 2023/04/22 17:30:35 rillig Exp $	*/
+/*	$NetBSD: msg_247.c,v 1.29 2023/04/22 17:42:29 rillig Exp $	*/
 # 3 "msg_247.c"
 
 // Test for message: pointer cast from '%s' to '%s' may be troublesome [247]
@@ -367,20 +367,17 @@ conversions_from_and_to_union(void)
 
 	/* expect+1: warning: illegal combination of 'pointer to union typedef anything' and 'pointer to double', op '=' [124] */
 	p_anything = p_double;
-	/*  FIXME: OK, since the union 'anything' has a 'double' member. */
-	/* expect+1: warning: pointer cast from 'pointer to double' to 'pointer to union typedef anything' may be troublesome [247] */
+	/* OK, since the union 'anything' has a 'double' member. */
 	p_anything = (anything *)p_double;
 	/* expect+1: warning: illegal combination of 'pointer to double' and 'pointer to union typedef anything', op '=' [124] */
 	p_double = p_anything;
-	/* FIXME: OK, since the union 'anything' has a 'double' member. */
-	/* expect+1: warning: pointer cast from 'pointer to union typedef anything' to 'pointer to double' may be troublesome [247] */
+	/* OK, since the union 'anything' has a 'double' member. */
 	p_double = (double *)p_anything;
 
 	/*
 	 * Casting to an intermediate union does not make casting between two
 	 * incompatible types better.
 	 */
-	/* expect+2: warning: pointer cast from 'pointer to int' to 'pointer to union typedef anything' may be troublesome [247] */
 	/* expect+1: warning: illegal combination of 'pointer to function(void) returning void' and 'pointer to union typedef anything', op '=' [124] */
 	p_function = (anything *)p_int;
 

Index: src/usr.bin/xlint/lint1/tree.c
diff -u src/usr.bin/xlint/lint1/tree.c:1.515 src/usr.bin/xlint/lint1/tree.c:1.516
--- src/usr.bin/xlint/lint1/tree.c:1.515	Sat Apr 22 15:14:37 2023
+++ src/usr.bin/xlint/lint1/tree.c	Sat Apr 22 17:42:29 2023
@@ -1,4 +1,4 @@
-/*	$NetBSD: tree.c,v 1.515 2023/04/22 15:14:37 rillig Exp $	*/
+/*	$NetBSD: tree.c,v 1.516 2023/04/22 17:42:29 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.515 2023/04/22 15:14:37 rillig Exp $");
+__RCSID("$NetBSD: tree.c,v 1.516 2023/04/22 17:42:29 rillig Exp $");
 #endif
 
 #include <float.h>
@@ -3491,6 +3491,17 @@ should_warn_about_pointer_cast(const typ
 			return false;
 	}
 
+	if (nst == UNION || ost == UNION) {
+		const type_t *union_tp = nst == UNION ? nstp : ostp;
+		const type_t *other_tp = nst == UNION ? ostp : nstp;
+		for (const sym_t *mem = union_tp->t_str->sou_first_member;
+		     mem != NULL; mem = mem->s_next) {
+			if (types_compatible(mem->s_type, other_tp,
+			    true, false, NULL))
+				return false;
+		}
+	}
+
 	if (is_struct_or_union(nst) && nstp->t_str != ostp->t_str)
 		return true;
 

Reply via email to