1*951d0648Srillig /* $NetBSD: msg_135.c,v 1.15 2023/04/23 11:52:43 rillig Exp $ */
2a0a15c14Srillig # 3 "msg_135.c"
3a0a15c14Srillig
4d39a5630Srillig // Test for message: converting '%s' to '%s' increases alignment from %u to %u [135]
5a0a15c14Srillig
6b2baa501Srillig /* lint1-extra-flags: -h -X 351 */
71a77a0d0Srillig
8814d2d42Srillig void sink(const void *);
9814d2d42Srillig
101a77a0d0Srillig unsigned
read_uint(const unsigned short ** pp)11915d5cedSrillig read_uint(const unsigned short **pp)
121a77a0d0Srillig {
131a77a0d0Srillig unsigned val;
141a77a0d0Srillig
15d39a5630Srillig /* expect+1: warning: converting 'pointer to const unsigned short' to 'pointer to const unsigned int' increases alignment from 2 to 4 [135] */
16915d5cedSrillig val = *(const unsigned *)(*pp);
171a77a0d0Srillig pp += sizeof(unsigned);
181a77a0d0Srillig return val;
191a77a0d0Srillig }
20814d2d42Srillig
215d41e58aSrillig /* expect+1: warning: struct 'incomplete' never defined [233] */
225d41e58aSrillig struct incomplete;
23814d2d42Srillig
24814d2d42Srillig struct complete {
25814d2d42Srillig int member;
26814d2d42Srillig };
27814d2d42Srillig
28814d2d42Srillig /*
29814d2d42Srillig * These types of conversions are typically seen in OpenSSL, when converting
30814d2d42Srillig * from the publicly visible, incomplete 'struct lhash_st' to a private
31814d2d42Srillig * implementation type such as 'struct lhash_st_OPENSSL_STRING'.
32814d2d42Srillig *
33c322b8c5Srillig * Before tree.c 1.277 from 2021-04-17, lint warned about this, even though
34c322b8c5Srillig * there was not enough evidence that there really was an alignment problem,
35c322b8c5Srillig * resulting in many false positives.
36c322b8c5Srillig *
37814d2d42Srillig * See openssl/lhash.h.
38814d2d42Srillig */
39814d2d42Srillig void
pointer_to_structs(struct incomplete * incomplete)40814d2d42Srillig pointer_to_structs(struct incomplete *incomplete)
41814d2d42Srillig {
42814d2d42Srillig struct complete *complete;
43814d2d42Srillig
44c322b8c5Srillig complete = (struct complete *)incomplete;
45814d2d42Srillig sink(complete);
46814d2d42Srillig }
478efa1be5Srillig
48915d5cedSrillig /*
49915d5cedSrillig * Before tree.c 1.316 from 2021-07-15, lint warned about pointer casts from
50915d5cedSrillig * unsigned char or plain char to another type. These casts often occur in
51915d5cedSrillig * traditional code that does not use void pointers, even 30 years after C90
52915d5cedSrillig * introduced 'void'.
53915d5cedSrillig */
548efa1be5Srillig void
unsigned_char_to_unsigned_type(unsigned char * ucp)558efa1be5Srillig unsigned_char_to_unsigned_type(unsigned char *ucp)
568efa1be5Srillig {
578efa1be5Srillig unsigned short *usp;
588efa1be5Srillig
598efa1be5Srillig usp = (unsigned short *)ucp;
608efa1be5Srillig sink(usp);
618efa1be5Srillig }
628efa1be5Srillig
63915d5cedSrillig /*
64915d5cedSrillig * Before tree.c 1.316 from 2021-07-15, lint warned about pointer casts from
65915d5cedSrillig * unsigned char or plain char to another type. These casts often occur in
66915d5cedSrillig * traditional code that does not use void pointers, even 30 years after C90
67915d5cedSrillig * introduced 'void'.
68915d5cedSrillig */
698efa1be5Srillig void
plain_char_to_unsigned_type(char * cp)708efa1be5Srillig plain_char_to_unsigned_type(char *cp)
718efa1be5Srillig {
728efa1be5Srillig unsigned short *usp;
738efa1be5Srillig
748efa1be5Srillig usp = (unsigned short *)cp;
758efa1be5Srillig sink(usp);
768efa1be5Srillig }
77a143ec61Srillig
78a143ec61Srillig /*
79a143ec61Srillig * Converting a pointer with a low alignment requirement to a union that
80*951d0648Srillig * includes other types with higher alignment requirements is considered safe.
81*951d0648Srillig * While accessing any other member of the union might trigger an alignment
82*951d0648Srillig * violation, such an access is not likely from an application point of view,
83*951d0648Srillig * as it would access undefined memory and thus invoke undefined behavior.
84a143ec61Srillig *
85a143ec61Srillig * A practical case for this pattern are tagged unions, in which the first
86a143ec61Srillig * member of the struct determines how the remaining members are interpreted.
87a143ec61Srillig * See sbin/newfs_udf, function udf_validate_tag_and_crc_sums for an example.
88*951d0648Srillig *
89*951d0648Srillig * C99 6.2.5p26 defines the representation and alignment of types, stating
90*951d0648Srillig * that pointers to union types need not have the same representation and
91*951d0648Srillig * alignment as pointers to other types.
92*951d0648Srillig *
93*951d0648Srillig * C99 6.7.2.1p14 and C23 6.7.2.1p18 both state that a "pointer to a union
94*951d0648Srillig * object [...] points to each of its members [...], and vice versa".
95a143ec61Srillig */
96a143ec61Srillig double
cast_to_union(void)97a143ec61Srillig cast_to_union(void)
98a143ec61Srillig {
99a143ec61Srillig int align_4 = 0;
100a143ec61Srillig double align_8 = 0.0;
101a143ec61Srillig union both {
102a143ec61Srillig int p_align_4;
103a143ec61Srillig double p_align_8;
104a143ec61Srillig } *both;
105a143ec61Srillig
106a143ec61Srillig both = (union both *)&align_4;
107a143ec61Srillig both = (union both *)&align_8;
108a143ec61Srillig return both->p_align_8;
109a143ec61Srillig }
110