xref: /netbsd-src/tests/usr.bin/xlint/lint1/msg_132_ilp32.c (revision 2718af68c3efc72c9769069b5c7f9ed36f6b9def)
1 /*	$NetBSD: msg_132_ilp32.c,v 1.1 2021/08/25 22:04:52 rillig Exp $	*/
2 # 3 "msg_132_ilp32.c"
3 
4 // Test for message: conversion from '%s' to '%s' may lose accuracy [132]
5 
6 /*
7  * On 32-bit platforms, it is possible to add a 64-bit integer to a 32-bit
8  * pointer.  The 64-bit integer is then converted to the ptrdiff_t of the
9  * target platform, which results in the non-obvious conversion from
10  * 'long long' to either 'long' or 'int', depending on the platform's
11  * ptrdiff_t.
12  */
13 
14 /* lint1-extra-flags: -a */
15 /* lint1-only-if: ilp32 int */
16 
17 /*
18  * Seen in usr.bin/make/var.c, function RegexReplace, in the function call
19  * SepBuf_AddBytesBetween(buf, wp + m[0].rm_so, wp + m[0].rm_eo).  The
20  * offsets of regular expression matches have type off_t, which is a 64-bit
21  * integer.
22  *
23  * C11 6.5.6p8 does not explicitly define the meaning of a pointer + an
24  * overly long integer, it just says "undefined behavior" if the resulting
25  * pointer would be outside the object.
26  */
27 const char *
28 array_subscript(const char *p, long long idx)
29 {
30 	/* expect+1: warning: conversion from 'long long' to 'int' may lose accuracy [132] */
31 	return p + idx;
32 }
33