1 /* $NetBSD: queries.c,v 1.9 2023/01/15 14:00:09 rillig Exp $ */ 2 # 3 "queries.c" 3 4 /* 5 * Demonstrate the case-by-case queries. Unlike warnings, queries do not 6 * point to questionable code but rather to code that may be interesting to 7 * inspect manually on a case-by-case basis. 8 * 9 * Possible use cases are: 10 * 11 * Understanding how C works internally, by making the usual arithmetic 12 * conversions visible. 13 * 14 * Finding code that intentionally suppresses a regular lint warning, 15 * such as casts between arithmetic types. 16 */ 17 18 /* lint1-extra-flags: -q 1,2,3,4,5,6,7 */ 19 20 typedef unsigned char u8_t; 21 typedef unsigned short u16_t; 22 typedef unsigned int u32_t; 23 typedef unsigned long long u64_t; 24 typedef signed char s8_t; 25 typedef signed short s16_t; 26 typedef signed int s32_t; 27 typedef signed long long s64_t; 28 29 typedef float f32_t; 30 typedef double f64_t; 31 typedef float _Complex c32_t; 32 typedef double _Complex c64_t; 33 34 typedef char *str_t; 35 typedef const char *cstr_t; 36 typedef volatile char *vstr_t; 37 38 _Bool cond; 39 40 u8_t u8; 41 u16_t u16; 42 u32_t u32; 43 u64_t u64; 44 45 s8_t s8; 46 s16_t s16; 47 s32_t s32; 48 s64_t s64; 49 50 struct { 51 unsigned u8:8; 52 unsigned u9:9; 53 unsigned u10:10; 54 unsigned u32:32; 55 int s8:8; 56 int s9:9; 57 int s10:10; 58 int s32:32; 59 } bits; 60 61 f32_t f32; 62 f64_t f64; 63 64 c32_t c32; 65 c64_t c64; 66 67 char *str; 68 const char *cstr; 69 volatile char *vstr; 70 71 int 72 Q1(double dbl) 73 { 74 /* expect+1: implicit conversion from floating point 'double' to integer 'int' [Q1] */ 75 return dbl; 76 } 77 78 int 79 Q2(double dbl) 80 { 81 /* expect+1: cast from floating point 'double' to integer 'int' [Q2] */ 82 return (int)dbl; 83 } 84 85 void 86 Q3(int i, unsigned u) 87 { 88 /* expect+1: implicit conversion changes sign from 'int' to 'unsigned int' [Q3] */ 89 u = i; 90 91 /* expect+1: implicit conversion changes sign from 'unsigned int' to 'int' [Q3] */ 92 i = u; 93 } 94 95 unsigned long long 96 Q4(signed char *ptr, int i, unsigned long long ull) 97 { 98 99 /* 100 * For constants, the usual arithmetic conversions are usually not 101 * interesting, so omit them. 102 */ 103 u32 = u32 & 0xff; 104 u32 &= 0xff; 105 106 /* expect+2: usual arithmetic conversion for '&' from 'int' to 'unsigned int' [Q4] */ 107 /* expect+1: implicit conversion changes sign from 'int' to 'unsigned int' [Q3] */ 108 u32 = u32 & s32; 109 /* 110 * XXX: C99 5.6.16.2 says that the usual arithmetic conversions 111 * happen for compound assignments as well. 112 */ 113 /* expect+1: implicit conversion changes sign from 'int' to 'unsigned int' [Q3] */ 114 u32 &= s32; 115 116 /* expect+3: implicit conversion changes sign from 'unsigned char' to 'int' [Q3] */ 117 /* expect+2: usual arithmetic conversion for '&' from 'int' to 'unsigned int' [Q4] */ 118 /* expect+1: implicit conversion changes sign from 'int' to 'unsigned int' [Q3] */ 119 u32 = u32 & u8; 120 121 /* 122 * The conversion from 'signed char' to 'int' is done by the integer 123 * promotions (C11 6.3.1.1p2), not by the usual arithmetic 124 * conversions (C11 6.3.1.8p1). 125 */ 126 /* expect+2: usual arithmetic conversion for '+' from 'int' to 'unsigned long long' [Q4] */ 127 /* expect+1: implicit conversion changes sign from 'int' to 'unsigned long long' [Q3] */ 128 return ptr[0] + ptr[1] + i + ull; 129 } 130 131 void 132 Q5(signed char *ptr, int i) 133 { 134 if (ptr + i > ptr) 135 return; 136 137 /* expect+1: pointer addition has integer on the left-hand side [Q5] */ 138 if (i + ptr > ptr) 139 return; 140 141 if (ptr[i] != '\0') 142 return; 143 144 /* expect+1: pointer addition has integer on the left-hand side [Q5] */ 145 if (i[ptr] != '\0') 146 return; 147 } 148 149 void 150 Q6(int i) 151 { 152 /* expect+1: no-op cast from 'int' to 'int' [Q6] */ 153 i = (int)4; 154 155 /* expect+1: no-op cast from 'int' to 'int' [Q6] */ 156 i = (int)i + 1; 157 } 158 159 extern void *allocate(void); 160 161 void 162 Q7(void) 163 { 164 165 /* expect+2: no-op cast from '_Bool' to '_Bool' [Q6] */ 166 /* expect+1: redundant cast from '_Bool' to '_Bool' before assignment [Q7] */ 167 cond = (_Bool)cond; 168 cond = (_Bool)u8; 169 u8 = (u8_t)cond; 170 171 /* expect+2: no-op cast from 'unsigned char' to 'unsigned char' [Q6] */ 172 /* expect+1: redundant cast from 'unsigned char' to 'unsigned char' before assignment [Q7] */ 173 u8 = (u8_t)u8; 174 u8 = (u8_t)u16; 175 u8 = (u16_t)u8; 176 /* expect+1: no-op cast from 'unsigned short' to 'unsigned short' [Q6] */ 177 u8 = (u16_t)u16; 178 /* expect+1: no-op cast from 'unsigned char' to 'unsigned char' [Q6] */ 179 u16 = (u8_t)u8; 180 u16 = (u8_t)u16; 181 /* expect+1: redundant cast from 'unsigned char' to 'unsigned short' before assignment [Q7] */ 182 u16 = (u16_t)u8; 183 /* expect+2: no-op cast from 'unsigned short' to 'unsigned short' [Q6] */ 184 /* expect+1: redundant cast from 'unsigned short' to 'unsigned short' before assignment [Q7] */ 185 u16 = (u16_t)u16; 186 187 /* Mixing signed and unsigned types. */ 188 u8 = (u8_t)s8; 189 s8 = (s8_t)u8; 190 /* expect+1: redundant cast from 'unsigned char' to 'short' before assignment [Q7] */ 191 s16 = (s16_t)u8; 192 /* expect+1: redundant cast from 'signed char' to 'short' before assignment [Q7] */ 193 s16 = (s16_t)s8; 194 195 196 /* 197 * Neither GCC nor Clang accept typeof(bit-field), as that would add 198 * unnecessary complexity. Lint accepts it but silently discards the 199 * bit-field portion from the type; see dcs_add_type. 200 */ 201 /* expect+1: redundant cast from 'unsigned char' to 'unsigned int' before assignment [Q7] */ 202 bits.u9 = (typeof(bits.u9))u8; 203 204 205 /* expect+2: no-op cast from 'float' to 'float' [Q6] */ 206 /* expect+1: redundant cast from 'float' to 'float' before assignment [Q7] */ 207 f32 = (f32_t)f32; 208 f32 = (f32_t)f64; 209 f32 = (f64_t)f32; 210 /* expect+1: no-op cast from 'double' to 'double' [Q6] */ 211 f32 = (f64_t)f64; 212 /* expect+1: no-op cast from 'float' to 'float' [Q6] */ 213 f64 = (f32_t)f32; 214 f64 = (f32_t)f64; 215 /* expect+1: redundant cast from 'float' to 'double' before assignment [Q7] */ 216 f64 = (f64_t)f32; 217 /* expect+2: no-op cast from 'double' to 'double' [Q6] */ 218 /* expect+1: redundant cast from 'double' to 'double' before assignment [Q7] */ 219 f64 = (f64_t)f64; 220 221 222 /* expect+2: no-op cast from 'float _Complex' to 'float _Complex' [Q6] */ 223 /* expect+1: redundant cast from 'float _Complex' to 'float _Complex' before assignment [Q7] */ 224 c32 = (c32_t)c32; 225 c32 = (c32_t)c64; 226 c32 = (c64_t)c32; 227 /* expect+1: no-op cast from 'double _Complex' to 'double _Complex' [Q6] */ 228 c32 = (c64_t)c64; 229 /* expect+1: no-op cast from 'float _Complex' to 'float _Complex' [Q6] */ 230 c64 = (c32_t)c32; 231 c64 = (c32_t)c64; 232 /* expect+1: redundant cast from 'float _Complex' to 'double _Complex' before assignment [Q7] */ 233 c64 = (c64_t)c32; 234 /* expect+2: no-op cast from 'double _Complex' to 'double _Complex' [Q6] */ 235 /* expect+1: redundant cast from 'double _Complex' to 'double _Complex' before assignment [Q7] */ 236 c64 = (c64_t)c64; 237 238 239 /* Mixing real and complex floating point types. */ 240 /* expect+1: no-op cast from 'float' to 'float' [Q6] */ 241 c32 = (f32_t)f32; 242 c32 = (c32_t)f32; 243 /* expect+1: no-op cast from 'float' to 'float' [Q6] */ 244 c64 = (f32_t)f32; 245 c64 = (f64_t)f32; 246 c64 = (c32_t)f32; 247 c64 = (c64_t)f32; 248 249 250 /* 251 * Converting a void pointer type to an object pointer type requires 252 * an explicit cast in C++, as it is a narrowing conversion. In C, 253 * that conversion is done implicitly. 254 */ 255 256 /* expect+1: redundant cast from 'pointer to void' to 'pointer to char' before assignment [Q7] */ 257 str = (char *)allocate(); 258 /* expect+1: redundant cast from 'pointer to void' to 'pointer to const char' before assignment [Q7] */ 259 cstr = (const char *)allocate(); 260 cstr = (char *)allocate(); 261 262 /* expect+2: no-op cast from 'pointer to char' to 'pointer to char' [Q6] */ 263 /* expect+1: redundant cast from 'pointer to char' to 'pointer to char' before assignment [Q7] */ 264 str = (str_t)str; 265 str = (str_t)cstr; 266 /* expect+1: warning: operands of '=' have incompatible pointer types to 'char' and 'const char' [128] */ 267 str = (cstr_t)str; 268 /* expect+2: no-op cast from 'pointer to const char' to 'pointer to const char' [Q6] */ 269 /* expect+1: warning: operands of '=' have incompatible pointer types to 'char' and 'const char' [128] */ 270 str = (cstr_t)cstr; 271 /* expect+1: no-op cast from 'pointer to char' to 'pointer to char' [Q6] */ 272 cstr = (str_t)str; 273 cstr = (str_t)cstr; 274 cstr = (cstr_t)str; 275 /* expect+2: no-op cast from 'pointer to const char' to 'pointer to const char' [Q6] */ 276 /* expect+1: redundant cast from 'pointer to const char' to 'pointer to const char' before assignment [Q7] */ 277 cstr = (cstr_t)cstr; 278 279 /* expect+2: no-op cast from 'pointer to char' to 'pointer to char' [Q6] */ 280 /* expect+1: redundant cast from 'pointer to char' to 'pointer to char' before assignment [Q7] */ 281 str = (str_t)str; 282 str = (str_t)vstr; 283 /* expect+1: warning: operands of '=' have incompatible pointer types to 'char' and 'volatile char' [128] */ 284 str = (vstr_t)str; 285 /* expect+2: no-op cast from 'pointer to volatile char' to 'pointer to volatile char' [Q6] */ 286 /* expect+1: warning: operands of '=' have incompatible pointer types to 'char' and 'volatile char' [128] */ 287 str = (vstr_t)vstr; 288 /* expect+1: no-op cast from 'pointer to char' to 'pointer to char' [Q6] */ 289 vstr = (str_t)str; 290 vstr = (str_t)vstr; 291 vstr = (vstr_t)str; 292 /* expect+2: no-op cast from 'pointer to volatile char' to 'pointer to volatile char' [Q6] */ 293 /* expect+1: redundant cast from 'pointer to volatile char' to 'pointer to volatile char' before assignment [Q7] */ 294 vstr = (vstr_t)vstr; 295 } 296 297 298 /* 299 * Since queries do not affect the exit status, force a warning to make this 300 * test conform to the general expectation that a test that produces output 301 * exits non-successfully. 302 */ 303 /* expect+1: warning: static variable 'unused' unused [226] */ 304 static int unused; 305