summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrillig <rillig@NetBSD.org>2023-04-22 19:45:04 +0000
committerrillig <rillig@NetBSD.org>2023-04-22 19:45:04 +0000
commitfc84fcc64b0eed2400c99bad75ea338ccfbfefe3 (patch)
treeb5863efcf297e9357082dd12bcdf110091b53582
parent32b69b78946214e6b7de182bb9f978fbea412076 (diff)
tests/lint: test cast to union with stricter alignment
-rw-r--r--tests/usr.bin/xlint/lint1/msg_135.c31
1 files changed, 29 insertions, 2 deletions
diff --git a/tests/usr.bin/xlint/lint1/msg_135.c b/tests/usr.bin/xlint/lint1/msg_135.c
index 917d72731d4..c29b1455aa6 100644
--- a/tests/usr.bin/xlint/lint1/msg_135.c
+++ b/tests/usr.bin/xlint/lint1/msg_135.c
@@ -1,4 +1,4 @@
-/* $NetBSD: msg_135.c,v 1.12 2023/03/28 14:44:34 rillig Exp $ */
+/* $NetBSD: msg_135.c,v 1.13 2023/04/22 19:45:04 rillig Exp $ */
# 3 "msg_135.c"
// Test for message: converting '%s' to '%s' increases alignment from %u to %u [135]
@@ -22,7 +22,7 @@ read_uint(const unsigned short **pp)
struct incomplete;
struct complete {
- int member;
+ int member;
};
/*
@@ -74,3 +74,30 @@ plain_char_to_unsigned_type(char *cp)
usp = (unsigned short *)cp;
sink(usp);
}
+
+/*
+ * Converting a pointer with a low alignment requirement to a union that
+ * includes other types with higher alignment requirements is safe. While
+ * accessing any other member of the union might trigger an alignment
+ * violation, such an access would invoke undefined behavior anyway.
+ *
+ * A practical case for this pattern are tagged unions, in which the first
+ * member of the struct determines how the remaining members are interpreted.
+ * See sbin/newfs_udf, function udf_validate_tag_and_crc_sums for an example.
+ */
+double
+cast_to_union(void)
+{
+ int align_4 = 0;
+ double align_8 = 0.0;
+ union both {
+ int p_align_4;
+ double p_align_8;
+ } *both;
+
+ /* TODO: don't warn here. */
+ /* expect+1: warning: converting 'pointer to int' to 'pointer to union both' increases alignment from 4 to 8 [135] */
+ both = (union both *)&align_4;
+ both = (union both *)&align_8;
+ return both->p_align_8;
+}