msg_132_ilp32.c revision 1.3 1 1.3 rillig /* $NetBSD: msg_132_ilp32.c,v 1.3 2023/03/28 14:44:34 rillig Exp $ */
2 1.1 rillig # 3 "msg_132_ilp32.c"
3 1.1 rillig
4 1.1 rillig // Test for message: conversion from '%s' to '%s' may lose accuracy [132]
5 1.1 rillig
6 1.1 rillig /*
7 1.1 rillig * On 32-bit platforms, it is possible to add a 64-bit integer to a 32-bit
8 1.1 rillig * pointer. The 64-bit integer is then converted to the ptrdiff_t of the
9 1.1 rillig * target platform, which results in the non-obvious conversion from
10 1.1 rillig * 'long long' to either 'long' or 'int', depending on the platform's
11 1.1 rillig * ptrdiff_t.
12 1.1 rillig */
13 1.1 rillig
14 1.1 rillig /* lint1-only-if: ilp32 int */
15 1.3 rillig /* lint1-extra-flags: -a -X 351 */
16 1.1 rillig
17 1.1 rillig /*
18 1.1 rillig * Seen in usr.bin/make/var.c, function RegexReplace, in the function call
19 1.1 rillig * SepBuf_AddBytesBetween(buf, wp + m[0].rm_so, wp + m[0].rm_eo). The
20 1.1 rillig * offsets of regular expression matches have type off_t, which is a 64-bit
21 1.1 rillig * integer.
22 1.1 rillig *
23 1.1 rillig * C11 6.5.6p8 does not explicitly define the meaning of a pointer + an
24 1.1 rillig * overly long integer, it just says "undefined behavior" if the resulting
25 1.1 rillig * pointer would be outside the object.
26 1.1 rillig */
27 1.1 rillig const char *
28 1.1 rillig array_subscript(const char *p, long long idx)
29 1.1 rillig {
30 1.1 rillig /* expect+1: warning: conversion from 'long long' to 'int' may lose accuracy [132] */
31 1.1 rillig return p + idx;
32 1.1 rillig }
33 1.2 rillig
34 1.2 rillig /*
35 1.2 rillig * On ILP32 platforms, pointer, long and int have the same size, so there is
36 1.2 rillig * no loss of accuracy.
37 1.2 rillig */
38 1.2 rillig unsigned int
39 1.2 rillig convert_pointer_to_smaller_integer(void *ptr)
40 1.2 rillig {
41 1.2 rillig return (unsigned long)(ptr) >> 12;
42 1.2 rillig }
43