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