1 /* $NetBSD: msg_259.c,v 1.23 2023/07/09 10:42:07 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 37 void 38 change_in_type_width(char c, int i, long l) 39 { 40 plain_char(c); 41 signed_int(c); 42 /* No warning 259 on LP64, only on ILP32 */ 43 signed_long(c); 44 45 plain_char(i); /* XXX: why no warning? */ 46 signed_int(i); 47 /* No warning 259 on LP64, only on ILP32 */ 48 signed_long(i); 49 50 plain_char(l); /* XXX: why no warning? */ 51 /* expect+1: ... from 'long' to 'int' due to prototype [259] */ 52 signed_int(l); 53 signed_long(l); 54 } 55 56 /* 57 * Converting a signed integer type to its corresponding unsigned integer 58 * type (C99 6.2.5p6) is usually not a problem since the actual values of the 59 * expressions are usually not anywhere near the maximum signed value. From 60 * a technical standpoint, it is correct to warn here since even small 61 * negative numbers may result in very large positive numbers. 62 * 63 * A common case where it occurs is when the difference of two pointers is 64 * converted to size_t. The type ptrdiff_t is defined to be signed, but in 65 * many practical cases, the expression is '(end - start)', which makes the 66 * resulting value necessarily positive. 67 */ 68 void 69 small_integer_types(char c, signed char sc, unsigned char uc, 70 signed short ss, unsigned short us, 71 signed int si, unsigned int ui, 72 signed long long sll, unsigned long long ull) 73 { 74 plain_char(c); 75 plain_char(sc); 76 plain_char(uc); 77 plain_char(ss); 78 plain_char(us); 79 plain_char(si); 80 plain_char(ui); 81 plain_char(sll); 82 plain_char(ull); 83 84 signed_char(c); 85 signed_char(sc); 86 signed_char(uc); 87 signed_char(ss); 88 signed_char(us); 89 signed_char(si); 90 signed_char(ui); 91 signed_char(sll); 92 signed_char(ull); 93 94 unsigned_char(c); 95 unsigned_char(sc); 96 unsigned_char(uc); 97 unsigned_char(ss); 98 unsigned_char(us); 99 unsigned_char(si); 100 unsigned_char(ui); 101 unsigned_char(sll); 102 unsigned_char(ull); 103 104 signed_short(c); 105 signed_short(sc); 106 signed_short(uc); 107 signed_short(ss); 108 signed_short(us); 109 signed_short(si); 110 signed_short(ui); 111 signed_short(sll); 112 signed_short(ull); 113 114 unsigned_short(c); 115 unsigned_short(sc); 116 unsigned_short(uc); 117 unsigned_short(ss); 118 unsigned_short(us); 119 unsigned_short(si); 120 unsigned_short(ui); 121 unsigned_short(sll); 122 unsigned_short(ull); 123 } 124 125 /* 126 * This function tests, among others, the conversion from a signed integer 127 * type to its corresponding unsigned integer type. Warning 259 is not 128 * about lossy integer conversions but about ABI calling conventions. 129 * 130 * A common case where a conversion from a signed integer type to its 131 * corresponding unsigned integer type occurs is when the difference of two 132 * pointers is converted to size_t. The type ptrdiff_t is defined to be 133 * signed, but in many practical cases, the expression is '(end - start)', 134 * which makes the resulting value necessarily positive. 135 */ 136 void 137 signed_to_unsigned(int si, long sl, long long sll) 138 { 139 /* expect+1: warning: argument 1 is converted from 'int' to 'unsigned int' due to prototype [259] */ 140 unsigned_int(si); 141 142 /* expect+1: warning: argument 1 is converted from 'long' to 'unsigned int' due to prototype [259] */ 143 unsigned_int(sl); 144 145 /* expect+1: warning: argument 1 is converted from 'long long' to 'unsigned int' due to prototype [259] */ 146 unsigned_int(sll); 147 148 /* 149 * No warning here. Even though 'unsigned long' is 64 bits wide, it 150 * cannot represent negative 32-bit values. This lossy conversion is 151 * covered by message 297 instead, which requires nonstandard flags. 152 */ 153 unsigned_long(si); 154 155 /* expect+1: warning: argument 1 is converted from 'long' to 'unsigned long' due to prototype [259] */ 156 unsigned_long(sl); 157 /* expect+1: warning: argument 1 is converted from 'long long' to 'unsigned long' due to prototype [259] */ 158 unsigned_long(sll); 159 160 /* 161 * No warning here. Even though 'unsigned long long' is 64 bits 162 * wide, it cannot represent negative 32-bit values. This lossy 163 * conversion is covered by message 297 instead, which requires 164 * nonstandard flags. 165 */ 166 unsigned_long_long(si); 167 168 /* expect+1: warning: argument 1 is converted from 'long' to 'unsigned long long' due to prototype [259] */ 169 unsigned_long_long(sl); 170 171 /* expect+1: warning: argument 1 is converted from 'long long' to 'unsigned long long' due to prototype [259] */ 172 unsigned_long_long(sll); 173 } 174 175 void 176 unsigned_to_signed(unsigned int ui, unsigned long ul, unsigned long long ull) 177 { 178 /* expect+1: warning: argument 1 is converted from 'unsigned int' to 'int' due to prototype [259] */ 179 signed_int(ui); 180 /* expect+1: warning: argument 1 is converted from 'unsigned long' to 'int' due to prototype [259] */ 181 signed_int(ul); 182 /* expect+1: warning: argument 1 is converted from 'unsigned long long' to 'int' due to prototype [259] */ 183 signed_int(ull); 184 signed_long(ui); 185 /* expect+1: warning: argument 1 is converted from 'unsigned long' to 'long' due to prototype [259] */ 186 signed_long(ul); 187 /* expect+1: warning: argument 1 is converted from 'unsigned long long' to 'long' due to prototype [259] */ 188 signed_long(ull); 189 signed_long_long(ui); 190 /* expect+1: warning: argument 1 is converted from 'unsigned long' to 'long long' due to prototype [259] */ 191 signed_long_long(ul); 192 /* expect+1: warning: argument 1 is converted from 'unsigned long long' to 'long long' due to prototype [259] */ 193 signed_long_long(ull); 194 } 195 196 void 197 signed_to_signed(signed int si, signed long sl, signed long long sll) 198 { 199 signed_int(si); 200 /* expect+1: warning: argument 1 is converted from 'long' to 'int' due to prototype [259] */ 201 signed_int(sl); 202 /* expect+1: warning: argument 1 is converted from 'long long' to 'int' due to prototype [259] */ 203 signed_int(sll); 204 signed_long(si); 205 signed_long(sl); 206 /* expect+1: warning: argument 1 is converted from 'long long' to 'long' due to prototype [259] */ 207 signed_long(sll); 208 signed_long_long(si); 209 /* expect+1: warning: argument 1 is converted from 'long' to 'long long' due to prototype [259] */ 210 signed_long_long(sl); 211 signed_long_long(sll); 212 } 213 214 void 215 unsigned_to_unsigned(unsigned int ui, unsigned long ul, unsigned long long ull) 216 { 217 unsigned_int(ui); 218 /* expect+1: warning: argument 1 is converted from 'unsigned long' to 'unsigned int' due to prototype [259] */ 219 unsigned_int(ul); 220 /* expect+1: warning: argument 1 is converted from 'unsigned long long' to 'unsigned int' due to prototype [259] */ 221 unsigned_int(ull); 222 unsigned_long(ui); 223 unsigned_long(ul); 224 /* expect+1: warning: argument 1 is converted from 'unsigned long long' to 'unsigned long' due to prototype [259] */ 225 unsigned_long(ull); 226 unsigned_long_long(ui); 227 /* expect+1: warning: argument 1 is converted from 'unsigned long' to 'unsigned long long' due to prototype [259] */ 228 unsigned_long_long(ul); 229 unsigned_long_long(ull); 230 } 231 232 void 233 pass_sizeof_as_smaller_type(void) 234 { 235 /* 236 * Even though the expression has type size_t, it has a constant 237 * value that fits effortless into an 'unsigned int', it's so small 238 * that it would even fit into a 3-bit bit-field, so lint's warning 239 * may seem wrong here. 240 * 241 * This warning 259 is not about lossy integer conversion though but 242 * instead covers calling conventions that may differ between integer 243 * types of different sizes, and from that point of view, the 244 * constant, even though its value would fit in an unsigned int, is 245 * still passed as size_t. 246 */ 247 /* expect+1: warning: argument 1 is converted from 'unsigned long' to 'unsigned int' due to prototype [259] */ 248 unsigned_int(sizeof(int)); 249 } 250