Module Name:    src
Committed By:   rillig
Date:           Thu Apr  8 19:08:17 UTC 2021

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

Log Message:
tests/lint: add test for struct pointer cast


To generate a diff of this commit:
cvs rdiff -u -r1.8 -r1.9 src/tests/usr.bin/xlint/lint1/msg_247.c
cvs rdiff -u -r1.5 -r1.6 src/tests/usr.bin/xlint/lint1/msg_247.exp

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.8 src/tests/usr.bin/xlint/lint1/msg_247.c:1.9
--- src/tests/usr.bin/xlint/lint1/msg_247.c:1.8	Tue Mar 30 15:05:05 2021
+++ src/tests/usr.bin/xlint/lint1/msg_247.c	Thu Apr  8 19:08:17 2021
@@ -1,4 +1,4 @@
-/*	$NetBSD: msg_247.c,v 1.8 2021/03/30 15:05:05 rillig Exp $	*/
+/*	$NetBSD: msg_247.c,v 1.9 2021/04/08 19:08:17 rillig Exp $	*/
 # 3 "msg_247.c"
 
 // Test for message: pointer cast from '%s' to '%s' may be troublesome [247]
@@ -75,3 +75,45 @@ cast_to_void_pointer_then_to_char_pointe
 {
 	return (char *)(void *)arg;
 }
+
+
+/*
+ * When implementing types that have a public part that is exposed to the user
+ * (in this case 'struct counter') and a private part that is only visible to
+ * the implementation (in this case 'struct counter_impl'), a common
+ * implementation technique is to use a struct in which the public part is the
+ * first member.  C guarantees that the pointer to the first member is at the
+ * same address as the pointer to the whole struct.
+ *
+ * Seen in external/mpl/bind/dist/lib/isc/mem.c for struct isc_mem and
+ * isc__mem.
+ */
+
+struct counter {
+	int count;
+};
+
+struct counter_impl {
+	struct counter public_part;
+	int saved_count;
+};
+
+void *allocate(void);
+
+struct counter *
+new_type_interface(void)
+{
+	struct counter_impl *impl = allocate();
+	impl->public_part.count = 12345;
+	impl->saved_count = 12346;
+	return &impl->public_part;
+}
+
+void
+counter_increment(struct counter *counter)
+{
+	/* expect+1: 247 */
+	struct counter_impl *impl = (struct counter_impl *)counter;
+	impl->saved_count = impl->public_part.count;
+	impl->public_part.count++;
+}

Index: src/tests/usr.bin/xlint/lint1/msg_247.exp
diff -u src/tests/usr.bin/xlint/lint1/msg_247.exp:1.5 src/tests/usr.bin/xlint/lint1/msg_247.exp:1.6
--- src/tests/usr.bin/xlint/lint1/msg_247.exp:1.5	Fri Mar 26 16:59:19 2021
+++ src/tests/usr.bin/xlint/lint1/msg_247.exp	Thu Apr  8 19:08:17 2021
@@ -1,2 +1,3 @@
 msg_247.c(31): warning: pointer cast from 'pointer to struct Other' to 'pointer to struct <unnamed>' may be troublesome [247]
 msg_247.c(70): warning: pointer cast from 'pointer to struct Other' to 'pointer to signed char' may be troublesome [247]
+msg_247.c(116): warning: pointer cast from 'pointer to struct counter' to 'pointer to struct counter_impl' may be troublesome [247]

Reply via email to