Home | History | Annotate | Line # | Download | only in lint1
      1 /*	$NetBSD: msg_259.c,v 1.25 2024/06/09 10:27:39 rillig Exp $	*/
      2 # 3 "msg_259.c"
      3 
      4 // Test for message: argument %d is converted from '%s' to '%s' due to prototype [259]
      5 
      6 /*
      7  * This warning detects function calls that are translated in very different
      8  * translation environments, one where prototypes are omitted, and one where
      9  * prototypes are active.  It is possible to make such code interoperable,
     10  * but that requires that each argument is converted to its proper type by
     11  * the caller of the function.
     12  *
     13  * When lint is run with the '-s' flag, it no longer warns about code with
     14  * incompatibilities between traditional C and C90, therefore this test omits
     15  * all of the options '-t', '-s', '-S' and '-Ac11'.
     16  *
     17  * See also msg_297, which is about lossy integer conversions, but that
     18  * requires the flags -a -p -P, which are not enabled in the default NetBSD
     19  * build.
     20  */
     21 
     22 /* lint1-only-if: lp64 */
     23 /* lint1-flags: -g -h -w -X 351 */
     24 
     25 void plain_char(char);
     26 void signed_char(signed char);
     27 void unsigned_char(unsigned char);
     28 void signed_short(signed short);
     29 void unsigned_short(unsigned short);
     30 void signed_int(int);
     31 void unsigned_int(unsigned int);
     32 void signed_long(long);
     33 void unsigned_long(unsigned long);
     34 void signed_long_long(long long);
     35 void unsigned_long_long(unsigned long long);
     36 void take_float(float);
     37 
     38 void
     39 change_in_type_width(char c, int i, long l)
     40 {
     41 	plain_char(c);
     42 	signed_int(c);
     43 	/* No warning 259 on LP64, only on ILP32 */
     44 	signed_long(c);
     45 
     46 	plain_char(i);		/* XXX: why no warning? */
     47 	signed_int(i);
     48 	/* No warning 259 on LP64, only on ILP32 */
     49 	signed_long(i);
     50 
     51 	plain_char(l);		/* XXX: why no warning? */
     52 	/* expect+1: ... from 'long' to 'int' due to prototype [259] */
     53 	signed_int(l);
     54 	signed_long(l);
     55 }
     56 
     57 /*
     58  * Converting a signed integer type to its corresponding unsigned integer
     59  * type (C99 6.2.5p6) is usually not a problem since the actual values of the
     60  * expressions are usually not anywhere near the maximum signed value.  From
     61  * a technical standpoint, it is correct to warn here since even small
     62  * negative numbers may result in very large positive numbers.
     63  *
     64  * A common case where it occurs is when the difference of two pointers is
     65  * converted to size_t.  The type ptrdiff_t is defined to be signed, but in
     66  * many practical cases, the expression is '(end - start)', which makes the
     67  * resulting value necessarily positive.
     68  */
     69 void
     70 small_integer_types(char c, signed char sc, unsigned char uc,
     71 		    signed short ss, unsigned short us,
     72 		    signed int si, unsigned int ui,
     73 		    signed long long sll, unsigned long long ull)
     74 {
     75 	plain_char(c);
     76 	plain_char(sc);
     77 	plain_char(uc);
     78 	plain_char(ss);
     79 	plain_char(us);
     80 	plain_char(si);
     81 	plain_char(ui);
     82 	plain_char(sll);
     83 	plain_char(ull);
     84 
     85 	signed_char(c);
     86 	signed_char(sc);
     87 	signed_char(uc);
     88 	signed_char(ss);
     89 	signed_char(us);
     90 	signed_char(si);
     91 	signed_char(ui);
     92 	signed_char(sll);
     93 	signed_char(ull);
     94 
     95 	unsigned_char(c);
     96 	unsigned_char(sc);
     97 	unsigned_char(uc);
     98 	unsigned_char(ss);
     99 	unsigned_char(us);
    100 	unsigned_char(si);
    101 	unsigned_char(ui);
    102 	unsigned_char(sll);
    103 	unsigned_char(ull);
    104 
    105 	signed_short(c);
    106 	signed_short(sc);
    107 	signed_short(uc);
    108 	signed_short(ss);
    109 	signed_short(us);
    110 	signed_short(si);
    111 	signed_short(ui);
    112 	signed_short(sll);
    113 	signed_short(ull);
    114 
    115 	unsigned_short(c);
    116 	unsigned_short(sc);
    117 	unsigned_short(uc);
    118 	unsigned_short(ss);
    119 	unsigned_short(us);
    120 	unsigned_short(si);
    121 	unsigned_short(ui);
    122 	unsigned_short(sll);
    123 	unsigned_short(ull);
    124 }
    125 
    126 /*
    127  * This function tests, among others, the conversion from a signed integer
    128  * type to its corresponding unsigned integer type.  Warning 259 is not
    129  * about lossy integer conversions but about ABI calling conventions.
    130  *
    131  * A common case where a conversion from a signed integer type to its
    132  * corresponding unsigned integer type occurs is when the difference of two
    133  * pointers is converted to size_t.  The type ptrdiff_t is defined to be
    134  * signed, but in many practical cases, the expression is '(end - start)',
    135  * which makes the resulting value necessarily positive.
    136  */
    137 void
    138 signed_to_unsigned(int si, long sl, long long sll)
    139 {
    140 	/* expect+1: warning: argument 1 is converted from 'int' to 'unsigned int' due to prototype [259] */
    141 	unsigned_int(si);
    142 
    143 	/* expect+1: warning: argument 1 is converted from 'long' to 'unsigned int' due to prototype [259] */
    144 	unsigned_int(sl);
    145 
    146 	/* expect+1: warning: argument 1 is converted from 'long long' to 'unsigned int' due to prototype [259] */
    147 	unsigned_int(sll);
    148 
    149 	/*
    150 	 * No warning here.  Even though 'unsigned long' is 64 bits wide, it
    151 	 * cannot represent negative 32-bit values.  This lossy conversion is
    152 	 * covered by message 297 instead, which requires nonstandard flags.
    153 	 */
    154 	unsigned_long(si);
    155 
    156 	/* expect+1: warning: argument 1 is converted from 'long' to 'unsigned long' due to prototype [259] */
    157 	unsigned_long(sl);
    158 	/* expect+1: warning: argument 1 is converted from 'long long' to 'unsigned long' due to prototype [259] */
    159 	unsigned_long(sll);
    160 
    161 	/*
    162 	 * No warning here.  Even though 'unsigned long long' is 64 bits
    163 	 * wide, it cannot represent negative 32-bit values.  This lossy
    164 	 * conversion is covered by message 297 instead, which requires
    165 	 * nonstandard flags.
    166 	 */
    167 	unsigned_long_long(si);
    168 
    169 	/* expect+1: warning: argument 1 is converted from 'long' to 'unsigned long long' due to prototype [259] */
    170 	unsigned_long_long(sl);
    171 
    172 	/* expect+1: warning: argument 1 is converted from 'long long' to 'unsigned long long' due to prototype [259] */
    173 	unsigned_long_long(sll);
    174 }
    175 
    176 void
    177 unsigned_to_signed(unsigned int ui, unsigned long ul, unsigned long long ull)
    178 {
    179 	/* expect+1: warning: argument 1 is converted from 'unsigned int' to 'int' due to prototype [259] */
    180 	signed_int(ui);
    181 	/* expect+1: warning: argument 1 is converted from 'unsigned long' to 'int' due to prototype [259] */
    182 	signed_int(ul);
    183 	/* expect+1: warning: argument 1 is converted from 'unsigned long long' to 'int' due to prototype [259] */
    184 	signed_int(ull);
    185 	signed_long(ui);
    186 	/* expect+1: warning: argument 1 is converted from 'unsigned long' to 'long' due to prototype [259] */
    187 	signed_long(ul);
    188 	/* expect+1: warning: argument 1 is converted from 'unsigned long long' to 'long' due to prototype [259] */
    189 	signed_long(ull);
    190 	signed_long_long(ui);
    191 	/* expect+1: warning: argument 1 is converted from 'unsigned long' to 'long long' due to prototype [259] */
    192 	signed_long_long(ul);
    193 	/* expect+1: warning: argument 1 is converted from 'unsigned long long' to 'long long' due to prototype [259] */
    194 	signed_long_long(ull);
    195 }
    196 
    197 void
    198 signed_to_signed(signed int si, signed long sl, signed long long sll)
    199 {
    200 	signed_int(si);
    201 	/* expect+1: warning: argument 1 is converted from 'long' to 'int' due to prototype [259] */
    202 	signed_int(sl);
    203 	/* expect+1: warning: argument 1 is converted from 'long long' to 'int' due to prototype [259] */
    204 	signed_int(sll);
    205 	signed_long(si);
    206 	signed_long(sl);
    207 	/* expect+1: warning: argument 1 is converted from 'long long' to 'long' due to prototype [259] */
    208 	signed_long(sll);
    209 	signed_long_long(si);
    210 	/* expect+1: warning: argument 1 is converted from 'long' to 'long long' due to prototype [259] */
    211 	signed_long_long(sl);
    212 	signed_long_long(sll);
    213 }
    214 
    215 void
    216 unsigned_to_unsigned(unsigned int ui, unsigned long ul, unsigned long long ull)
    217 {
    218 	unsigned_int(ui);
    219 	/* expect+1: warning: argument 1 is converted from 'unsigned long' to 'unsigned int' due to prototype [259] */
    220 	unsigned_int(ul);
    221 	/* expect+1: warning: argument 1 is converted from 'unsigned long long' to 'unsigned int' due to prototype [259] */
    222 	unsigned_int(ull);
    223 	unsigned_long(ui);
    224 	unsigned_long(ul);
    225 	/* expect+1: warning: argument 1 is converted from 'unsigned long long' to 'unsigned long' due to prototype [259] */
    226 	unsigned_long(ull);
    227 	unsigned_long_long(ui);
    228 	/* expect+1: warning: argument 1 is converted from 'unsigned long' to 'unsigned long long' due to prototype [259] */
    229 	unsigned_long_long(ul);
    230 	unsigned_long_long(ull);
    231 }
    232 
    233 void
    234 constants(void)
    235 {
    236 	/* expect+2: warning: argument 1 is converted from 'long long' to 'unsigned int' due to prototype [259] */
    237 	/* expect+1: warning: conversion of 'long long' to 'unsigned int' is out of range, arg #1 [295] */
    238 	unsigned_int(0x7fffffffffffffffLL);
    239 	/* expect+2: warning: argument 1 is converted from 'double' to 'unsigned int' due to prototype [259] */
    240 	/* expect+1: warning: lossy conversion of 2.1 to 'unsigned int', arg #1 [380] */
    241 	unsigned_int(2.1);
    242 }
    243 
    244 void
    245 to_float(double dbl)
    246 {
    247 	/* expect+1: warning: argument 1 is converted from 'double' to 'float' due to prototype [259] */
    248 	take_float(dbl);
    249 }
    250 
    251 void
    252 pass_sizeof_as_smaller_type(void)
    253 {
    254 	/*
    255 	 * Even though the expression has type size_t, it has a constant
    256 	 * value that fits effortless into an 'unsigned int', it's so small
    257 	 * that it would even fit into a 3-bit bit-field, so lint's warning
    258 	 * may seem wrong here.
    259 	 *
    260 	 * This warning 259 is not about lossy integer conversion though but
    261 	 * instead covers calling conventions that may differ between integer
    262 	 * types of different sizes, and from that point of view, the
    263 	 * constant, even though its value would fit in an unsigned int, is
    264 	 * still passed as size_t.
    265 	 */
    266 	/* expect+1: warning: argument 1 is converted from 'unsigned long' to 'unsigned int' due to prototype [259] */
    267 	unsigned_int(sizeof(int));
    268 }
    269