xref: /netbsd-src/tests/usr.bin/xlint/lint1/queries.c (revision cd4ee416b8ecb6a5d3739b2d808bd6e8e4173867)
1*cd4ee416Srillig /*	$NetBSD: queries.c,v 1.33 2024/11/30 11:27:20 rillig Exp $	*/
2715e58e7Srillig # 3 "queries.c"
3715e58e7Srillig 
4715e58e7Srillig /*
5715e58e7Srillig  * Demonstrate the case-by-case queries.  Unlike warnings, queries do not
6715e58e7Srillig  * point to questionable code but rather to code that may be interesting to
7715e58e7Srillig  * inspect manually on a case-by-case basis.
8715e58e7Srillig  *
9715e58e7Srillig  * Possible use cases are:
10715e58e7Srillig  *
11715e58e7Srillig  *	Understanding how C works internally, by making the usual arithmetic
12715e58e7Srillig  *	conversions visible.
13715e58e7Srillig  *
14715e58e7Srillig  *	Finding code that intentionally suppresses a regular lint warning,
15715e58e7Srillig  *	such as casts between arithmetic types.
16715e58e7Srillig  */
17715e58e7Srillig 
18370056d3Srillig /* lint1-extra-flags: -q 1,2,3,4,5,6,7,8,9,10 */
1996381692Srillig /* lint1-extra-flags: -q 11,12,13,14,15,16,17,18,19,20 */
20b2ad51d9Srillig /* lint1-extra-flags: -q 21,22,23,24 */
21370056d3Srillig /* lint1-extra-flags: -X 351 */
22715e58e7Srillig 
239db688f9Srillig typedef unsigned char u8_t;
249db688f9Srillig typedef unsigned short u16_t;
259db688f9Srillig typedef unsigned int u32_t;
269db688f9Srillig typedef unsigned long long u64_t;
279db688f9Srillig typedef signed char s8_t;
289db688f9Srillig typedef signed short s16_t;
299db688f9Srillig typedef signed int s32_t;
309db688f9Srillig typedef signed long long s64_t;
319db688f9Srillig 
329db688f9Srillig typedef float f32_t;
339db688f9Srillig typedef double f64_t;
349db688f9Srillig typedef float _Complex c32_t;
359db688f9Srillig typedef double _Complex c64_t;
369db688f9Srillig 
37238d676fSrillig typedef char *str_t;
38238d676fSrillig typedef const char *cstr_t;
39238d676fSrillig typedef volatile char *vstr_t;
40def8e179Srillig typedef typeof(sizeof 0) size_t;
41238d676fSrillig 
42238d676fSrillig _Bool cond;
43238d676fSrillig 
449db688f9Srillig u8_t u8;
459db688f9Srillig u16_t u16;
469db688f9Srillig u32_t u32;
479db688f9Srillig u64_t u64;
489db688f9Srillig 
499db688f9Srillig s8_t s8;
509db688f9Srillig s16_t s16;
519db688f9Srillig s32_t s32;
529db688f9Srillig s64_t s64;
539db688f9Srillig 
549db688f9Srillig struct {
559db688f9Srillig 	unsigned u8:8;
569db688f9Srillig 	unsigned u9:9;
579db688f9Srillig 	unsigned u10:10;
589db688f9Srillig 	unsigned u32:32;
599db688f9Srillig 	int s8:8;
609db688f9Srillig 	int s9:9;
619db688f9Srillig 	int s10:10;
629db688f9Srillig 	int s32:32;
639db688f9Srillig } bits;
649db688f9Srillig 
659db688f9Srillig f32_t f32;
669db688f9Srillig f64_t f64;
679db688f9Srillig 
689db688f9Srillig c32_t c32;
699db688f9Srillig c64_t c64;
709db688f9Srillig 
719db688f9Srillig char *str;
729db688f9Srillig const char *cstr;
73238d676fSrillig volatile char *vstr;
7488d1eb23Srillig const volatile char *cvstr;
759db688f9Srillig 
760382e641Srillig void *void_ptr;
770382e641Srillig const void *const_void_ptr;
7896381692Srillig char *char_ptr;
7996381692Srillig int *int_ptr;
800382e641Srillig 
81715e58e7Srillig int
82715e58e7Srillig Q1(double dbl)
83715e58e7Srillig {
84715e58e7Srillig 	/* expect+1: implicit conversion from floating point 'double' to integer 'int' [Q1] */
85715e58e7Srillig 	return dbl;
86715e58e7Srillig }
87715e58e7Srillig 
88715e58e7Srillig int
89715e58e7Srillig Q2(double dbl)
90715e58e7Srillig {
919db688f9Srillig 	/* expect+1: cast from floating point 'double' to integer 'int' [Q2] */
92715e58e7Srillig 	return (int)dbl;
93715e58e7Srillig }
94715e58e7Srillig 
952bb36c11Srillig // The Q3 query triggers so often that it also occurs outside this function.
96715e58e7Srillig void
97715e58e7Srillig Q3(int i, unsigned u)
98715e58e7Srillig {
99715e58e7Srillig 	/* expect+1: implicit conversion changes sign from 'int' to 'unsigned int' [Q3] */
100715e58e7Srillig 	u = i;
101715e58e7Srillig 
102715e58e7Srillig 	/* expect+1: implicit conversion changes sign from 'unsigned int' to 'int' [Q3] */
103715e58e7Srillig 	i = u;
1042bb36c11Srillig 
1052bb36c11Srillig 	/* expect+2: implicit conversion changes sign from 'unsigned char' to 'int' [Q3] */
1062bb36c11Srillig 	/* expect+1: implicit conversion changes sign from 'int' to 'unsigned short' [Q3] */
1072bb36c11Srillig 	u16 += u8;
1082bb36c11Srillig 	/* expect+2: implicit conversion changes sign from 'unsigned short' to 'int' [Q3] */
1092bb36c11Srillig 	/* expect+1: implicit conversion changes sign from 'int' to 'unsigned int' [Q3] */
1102bb36c11Srillig 	u32 += u16;
111715e58e7Srillig }
112715e58e7Srillig 
113715e58e7Srillig unsigned long long
114def8e179Srillig Q4(signed char *ptr, int i, unsigned long long ull, size_t sz)
115715e58e7Srillig {
11612c5dc76Srillig 
117872114d0Srillig 	/*
118872114d0Srillig 	 * For constants, the usual arithmetic conversions are usually not
119872114d0Srillig 	 * interesting, so omit them.
120872114d0Srillig 	 */
12112c5dc76Srillig 	u32 = u32 & 0xff;
122872114d0Srillig 	u32 &= 0xff;
123872114d0Srillig 
124872114d0Srillig 	/* expect+2: usual arithmetic conversion for '&' from 'int' to 'unsigned int' [Q4] */
125872114d0Srillig 	/* expect+1: implicit conversion changes sign from 'int' to 'unsigned int' [Q3] */
126872114d0Srillig 	u32 = u32 & s32;
12712c5dc76Srillig 	/*
12812c5dc76Srillig 	 * XXX: C99 5.6.16.2 says that the usual arithmetic conversions
12912c5dc76Srillig 	 * happen for compound assignments as well.
13012c5dc76Srillig 	 */
131872114d0Srillig 	/* expect+1: implicit conversion changes sign from 'int' to 'unsigned int' [Q3] */
132872114d0Srillig 	u32 &= s32;
13312c5dc76Srillig 
13412c5dc76Srillig 	/* expect+3: implicit conversion changes sign from 'unsigned char' to 'int' [Q3] */
13512c5dc76Srillig 	/* expect+2: usual arithmetic conversion for '&' from 'int' to 'unsigned int' [Q4] */
13612c5dc76Srillig 	/* expect+1: implicit conversion changes sign from 'int' to 'unsigned int' [Q3] */
13712c5dc76Srillig 	u32 = u32 & u8;
13812c5dc76Srillig 
139def8e179Srillig 	s8 = ptr[sz];
140def8e179Srillig 
141715e58e7Srillig 	/*
1420f43f630Srillig 	 * The conversion from 'signed char' to 'int' is done by the integer
143715e58e7Srillig 	 * promotions (C11 6.3.1.1p2), not by the usual arithmetic
144715e58e7Srillig 	 * conversions (C11 6.3.1.8p1).
145715e58e7Srillig 	 */
146715e58e7Srillig 	/* expect+2: usual arithmetic conversion for '+' from 'int' to 'unsigned long long' [Q4] */
147715e58e7Srillig 	/* expect+1: implicit conversion changes sign from 'int' to 'unsigned long long' [Q3] */
148715e58e7Srillig 	return ptr[0] + ptr[1] + i + ull;
149715e58e7Srillig }
150715e58e7Srillig 
151715e58e7Srillig void
15207d76dc4Srillig Q5(signed char *ptr, int i)
153715e58e7Srillig {
154715e58e7Srillig 	if (ptr + i > ptr)
155715e58e7Srillig 		return;
156715e58e7Srillig 
157715e58e7Srillig 	/* expect+1: pointer addition has integer on the left-hand side [Q5] */
158715e58e7Srillig 	if (i + ptr > ptr)
159715e58e7Srillig 		return;
160715e58e7Srillig 
161715e58e7Srillig 	if (ptr[i] != '\0')
162715e58e7Srillig 		return;
163715e58e7Srillig 
164715e58e7Srillig 	/* expect+1: pointer addition has integer on the left-hand side [Q5] */
165715e58e7Srillig 	if (i[ptr] != '\0')
166715e58e7Srillig 		return;
167715e58e7Srillig }
168715e58e7Srillig 
169715e58e7Srillig void
170715e58e7Srillig Q6(int i)
171715e58e7Srillig {
172715e58e7Srillig 	/* expect+1: no-op cast from 'int' to 'int' [Q6] */
173715e58e7Srillig 	i = (int)4;
174715e58e7Srillig 
175715e58e7Srillig 	/* expect+1: no-op cast from 'int' to 'int' [Q6] */
176715e58e7Srillig 	i = (int)i + 1;
177715e58e7Srillig }
178715e58e7Srillig 
1794a6e7880Srillig void *allocate(void);
180715e58e7Srillig 
1819db688f9Srillig void
182715e58e7Srillig Q7(void)
183715e58e7Srillig {
184715e58e7Srillig 
185238d676fSrillig 	/* expect+2: no-op cast from '_Bool' to '_Bool' [Q6] */
186238d676fSrillig 	/* expect+1: redundant cast from '_Bool' to '_Bool' before assignment [Q7] */
187238d676fSrillig 	cond = (_Bool)cond;
188238d676fSrillig 	cond = (_Bool)u8;
189238d676fSrillig 	u8 = (u8_t)cond;
190238d676fSrillig 
1919db688f9Srillig 	/* expect+2: no-op cast from 'unsigned char' to 'unsigned char' [Q6] */
1929db688f9Srillig 	/* expect+1: redundant cast from 'unsigned char' to 'unsigned char' before assignment [Q7] */
1939db688f9Srillig 	u8 = (u8_t)u8;
1949db688f9Srillig 	u8 = (u8_t)u16;
1959db688f9Srillig 	u8 = (u16_t)u8;
1969db688f9Srillig 	/* expect+1: no-op cast from 'unsigned short' to 'unsigned short' [Q6] */
1979db688f9Srillig 	u8 = (u16_t)u16;
1989db688f9Srillig 	/* expect+1: no-op cast from 'unsigned char' to 'unsigned char' [Q6] */
1999db688f9Srillig 	u16 = (u8_t)u8;
2009db688f9Srillig 	u16 = (u8_t)u16;
2019db688f9Srillig 	/* expect+1: redundant cast from 'unsigned char' to 'unsigned short' before assignment [Q7] */
2029db688f9Srillig 	u16 = (u16_t)u8;
2039db688f9Srillig 	/* expect+2: no-op cast from 'unsigned short' to 'unsigned short' [Q6] */
2049db688f9Srillig 	/* expect+1: redundant cast from 'unsigned short' to 'unsigned short' before assignment [Q7] */
2059db688f9Srillig 	u16 = (u16_t)u16;
206715e58e7Srillig 
2079db688f9Srillig 	/* Mixing signed and unsigned types. */
2089db688f9Srillig 	u8 = (u8_t)s8;
2099db688f9Srillig 	s8 = (s8_t)u8;
2109db688f9Srillig 	/* expect+1: redundant cast from 'unsigned char' to 'short' before assignment [Q7] */
2119db688f9Srillig 	s16 = (s16_t)u8;
2129db688f9Srillig 	/* expect+1: redundant cast from 'signed char' to 'short' before assignment [Q7] */
2139db688f9Srillig 	s16 = (s16_t)s8;
2149db688f9Srillig 
2159db688f9Srillig 
2169db688f9Srillig 	/*
2179db688f9Srillig 	 * Neither GCC nor Clang accept typeof(bit-field), as that would add
2189db688f9Srillig 	 * unnecessary complexity.  Lint accepts it but silently discards the
2192676d014Srillig 	 * bit-field portion from the type; see dcs_add_type.
2209db688f9Srillig 	 */
2219db688f9Srillig 	/* expect+1: redundant cast from 'unsigned char' to 'unsigned int' before assignment [Q7] */
2229db688f9Srillig 	bits.u9 = (typeof(bits.u9))u8;
2239db688f9Srillig 
2249db688f9Srillig 
2259db688f9Srillig 	/* expect+2: no-op cast from 'float' to 'float' [Q6] */
2269db688f9Srillig 	/* expect+1: redundant cast from 'float' to 'float' before assignment [Q7] */
2279db688f9Srillig 	f32 = (f32_t)f32;
2289db688f9Srillig 	f32 = (f32_t)f64;
2299db688f9Srillig 	f32 = (f64_t)f32;
2309db688f9Srillig 	/* expect+1: no-op cast from 'double' to 'double' [Q6] */
2319db688f9Srillig 	f32 = (f64_t)f64;
2329db688f9Srillig 	/* expect+1: no-op cast from 'float' to 'float' [Q6] */
2339db688f9Srillig 	f64 = (f32_t)f32;
2349db688f9Srillig 	f64 = (f32_t)f64;
2359db688f9Srillig 	/* expect+1: redundant cast from 'float' to 'double' before assignment [Q7] */
2369db688f9Srillig 	f64 = (f64_t)f32;
2379db688f9Srillig 	/* expect+2: no-op cast from 'double' to 'double' [Q6] */
2389db688f9Srillig 	/* expect+1: redundant cast from 'double' to 'double' before assignment [Q7] */
2399db688f9Srillig 	f64 = (f64_t)f64;
2409db688f9Srillig 
2419db688f9Srillig 
2429db688f9Srillig 	/* expect+2: no-op cast from 'float _Complex' to 'float _Complex' [Q6] */
2439db688f9Srillig 	/* expect+1: redundant cast from 'float _Complex' to 'float _Complex' before assignment [Q7] */
2449db688f9Srillig 	c32 = (c32_t)c32;
2459db688f9Srillig 	c32 = (c32_t)c64;
2469db688f9Srillig 	c32 = (c64_t)c32;
2479db688f9Srillig 	/* expect+1: no-op cast from 'double _Complex' to 'double _Complex' [Q6] */
2489db688f9Srillig 	c32 = (c64_t)c64;
2499db688f9Srillig 	/* expect+1: no-op cast from 'float _Complex' to 'float _Complex' [Q6] */
2509db688f9Srillig 	c64 = (c32_t)c32;
2519db688f9Srillig 	c64 = (c32_t)c64;
2529db688f9Srillig 	/* expect+1: redundant cast from 'float _Complex' to 'double _Complex' before assignment [Q7] */
2539db688f9Srillig 	c64 = (c64_t)c32;
2549db688f9Srillig 	/* expect+2: no-op cast from 'double _Complex' to 'double _Complex' [Q6] */
2559db688f9Srillig 	/* expect+1: redundant cast from 'double _Complex' to 'double _Complex' before assignment [Q7] */
2569db688f9Srillig 	c64 = (c64_t)c64;
2579db688f9Srillig 
2589db688f9Srillig 
259238d676fSrillig 	/* Mixing real and complex floating point types. */
260238d676fSrillig 	/* expect+1: no-op cast from 'float' to 'float' [Q6] */
261238d676fSrillig 	c32 = (f32_t)f32;
262238d676fSrillig 	c32 = (c32_t)f32;
263238d676fSrillig 	/* expect+1: no-op cast from 'float' to 'float' [Q6] */
264238d676fSrillig 	c64 = (f32_t)f32;
265238d676fSrillig 	c64 = (f64_t)f32;
266238d676fSrillig 	c64 = (c32_t)f32;
267238d676fSrillig 	c64 = (c64_t)f32;
268238d676fSrillig 
269238d676fSrillig 
2708e78cfd5Srillig 	/*
2718e78cfd5Srillig 	 * Converting a void pointer type to an object pointer type requires
2728e78cfd5Srillig 	 * an explicit cast in C++, as it is a narrowing conversion. In C,
2738e78cfd5Srillig 	 * that conversion is done implicitly.
2748e78cfd5Srillig 	 */
2758e78cfd5Srillig 
2769db688f9Srillig 	/* expect+1: redundant cast from 'pointer to void' to 'pointer to char' before assignment [Q7] */
2779db688f9Srillig 	str = (char *)allocate();
2789db688f9Srillig 	/* expect+1: redundant cast from 'pointer to void' to 'pointer to const char' before assignment [Q7] */
2799db688f9Srillig 	cstr = (const char *)allocate();
2809db688f9Srillig 	cstr = (char *)allocate();
281238d676fSrillig 
282238d676fSrillig 	/* expect+2: no-op cast from 'pointer to char' to 'pointer to char' [Q6] */
283238d676fSrillig 	/* expect+1: redundant cast from 'pointer to char' to 'pointer to char' before assignment [Q7] */
284238d676fSrillig 	str = (str_t)str;
285238d676fSrillig 	str = (str_t)cstr;
28688d1eb23Srillig 	/* expect+1: warning: operator '=' discards 'const' from 'pointer to const char' [128] */
287238d676fSrillig 	str = (cstr_t)str;
288238d676fSrillig 	/* expect+2: no-op cast from 'pointer to const char' to 'pointer to const char' [Q6] */
28988d1eb23Srillig 	/* expect+1: warning: operator '=' discards 'const' from 'pointer to const char' [128] */
290238d676fSrillig 	str = (cstr_t)cstr;
291238d676fSrillig 	/* expect+1: no-op cast from 'pointer to char' to 'pointer to char' [Q6] */
292238d676fSrillig 	cstr = (str_t)str;
293238d676fSrillig 	cstr = (str_t)cstr;
294238d676fSrillig 	cstr = (cstr_t)str;
295238d676fSrillig 	/* expect+2: no-op cast from 'pointer to const char' to 'pointer to const char' [Q6] */
296238d676fSrillig 	/* expect+1: redundant cast from 'pointer to const char' to 'pointer to const char' before assignment [Q7] */
297238d676fSrillig 	cstr = (cstr_t)cstr;
298238d676fSrillig 
299238d676fSrillig 	/* expect+2: no-op cast from 'pointer to char' to 'pointer to char' [Q6] */
300238d676fSrillig 	/* expect+1: redundant cast from 'pointer to char' to 'pointer to char' before assignment [Q7] */
301238d676fSrillig 	str = (str_t)str;
302238d676fSrillig 	str = (str_t)vstr;
30388d1eb23Srillig 	/* expect+1: warning: operator '=' discards 'volatile' from 'pointer to volatile char' [128] */
304238d676fSrillig 	str = (vstr_t)str;
305238d676fSrillig 	/* expect+2: no-op cast from 'pointer to volatile char' to 'pointer to volatile char' [Q6] */
30688d1eb23Srillig 	/* expect+1: warning: operator '=' discards 'volatile' from 'pointer to volatile char' [128] */
307238d676fSrillig 	str = (vstr_t)vstr;
308238d676fSrillig 	/* expect+1: no-op cast from 'pointer to char' to 'pointer to char' [Q6] */
309238d676fSrillig 	vstr = (str_t)str;
310238d676fSrillig 	vstr = (str_t)vstr;
311238d676fSrillig 	vstr = (vstr_t)str;
312238d676fSrillig 	/* expect+2: no-op cast from 'pointer to volatile char' to 'pointer to volatile char' [Q6] */
313238d676fSrillig 	/* expect+1: redundant cast from 'pointer to volatile char' to 'pointer to volatile char' before assignment [Q7] */
314238d676fSrillig 	vstr = (vstr_t)vstr;
31588d1eb23Srillig 
31688d1eb23Srillig 	/* expect+1: warning: operator '=' discards 'const volatile' from 'pointer to const volatile char' [128] */
31788d1eb23Srillig 	str = cvstr;
31888d1eb23Srillig 	/* expect+1: warning: operator '=' discards 'volatile' from 'pointer to const volatile char' [128] */
31988d1eb23Srillig 	cstr = cvstr;
32088d1eb23Srillig 	/* expect+1: warning: operator '=' discards 'const' from 'pointer to const volatile char' [128] */
32188d1eb23Srillig 	vstr = cvstr;
322715e58e7Srillig }
323715e58e7Srillig 
324ce2e7177Srillig /*
325ce2e7177Srillig  * Octal numbers were common in the 1970s, especially on 36-bit machines.
326ce2e7177Srillig  * 50 years later, they are still used in numeric file permissions.
327ce2e7177Srillig  */
328ce2e7177Srillig void
329ce2e7177Srillig Q8(void)
330ce2e7177Srillig {
331ce2e7177Srillig 
332ce2e7177Srillig 	u16 = 0;
3335eee0b3dSrillig 	/* expect+1: octal number '000000' [Q8] */
334ce2e7177Srillig 	u16 = 000000;
335*cd4ee416Srillig 	/* expect+1: octal number '0123' [Q8] */
336*cd4ee416Srillig 	u16 = 0123ULL;
3375eee0b3dSrillig 	u16 = 1;
3385eee0b3dSrillig 	u16 = 10;
339ce2e7177Srillig 	/* expect+1: octal number '0644' [Q8] */
340ce2e7177Srillig 	u16 = 0644;
341ce2e7177Srillig 	/* expect+1: octal number '0000644' [Q8] */
342ce2e7177Srillig 	u16 = 0000644;
343ce2e7177Srillig }
344715e58e7Srillig 
345408e7ca2Srillig int
346408e7ca2Srillig Q9(int x)
347408e7ca2Srillig {
348408e7ca2Srillig 	switch (x) {
349408e7ca2Srillig 	case 0:
350408e7ca2Srillig 		return 0;
351408e7ca2Srillig 	case 1:
352408e7ca2Srillig 		/* expect+1: parenthesized return value [Q9] */
353408e7ca2Srillig 		return (0);
354408e7ca2Srillig 	case 2:
355408e7ca2Srillig 		return +(0);
356408e7ca2Srillig 	case 3:
357408e7ca2Srillig 		return -(13);
358408e7ca2Srillig 	case 4:
359ec19c40cSrillig 		/* expect+2: comma operator with types 'int' and 'int' [Q12] */
360408e7ca2Srillig 		/* expect+1: parenthesized return value [Q9] */
361408e7ca2Srillig 		return (0), (1);
362408e7ca2Srillig 	case 5:
363ec19c40cSrillig 		/* expect+2: comma operator with types 'int' and 'int' [Q12] */
364408e7ca2Srillig 		/* expect+1: parenthesized return value [Q9] */
365408e7ca2Srillig 		return (0, 1);
366408e7ca2Srillig 	case 6:
367ec19c40cSrillig 		/* expect+1: comma operator with types 'int' and 'int' [Q12] */
368408e7ca2Srillig 		return 0, 1;
369408e7ca2Srillig 	case 7:
370408e7ca2Srillig 		/* expect+1: implicit conversion from floating point 'double' to integer 'int' [Q1] */
371408e7ca2Srillig 		return 0.0;
372408e7ca2Srillig 	case 8:
373408e7ca2Srillig 		/* expect+2: parenthesized return value [Q9] */
374408e7ca2Srillig 		/* expect+1: implicit conversion from floating point 'double' to integer 'int' [Q1] */
375408e7ca2Srillig 		return (0.0);
376408e7ca2Srillig 	case 9:
377408e7ca2Srillig 		return
378*cd4ee416Srillig # 379 "queries.c" 3 4
379408e7ca2Srillig 		((void *)0)
380*cd4ee416Srillig # 381 "queries.c"
381408e7ca2Srillig 		/* expect+1: warning: illegal combination of integer 'int' and pointer 'pointer to void' [183] */
382408e7ca2Srillig 		;
383408e7ca2Srillig 	case 10:
384408e7ca2Srillig 		/* expect+1: warning: illegal combination of integer 'int' and pointer 'pointer to void' [183] */
385408e7ca2Srillig 		return (void *)(0);
386408e7ca2Srillig 	default:
387408e7ca2Srillig 		return 0;
388408e7ca2Srillig 	}
389408e7ca2Srillig }
390408e7ca2Srillig 
3914f2a6350Srillig void
3924f2a6350Srillig Q10(void)
3934f2a6350Srillig {
3944f2a6350Srillig 	int a, b, c;
3954f2a6350Srillig 
3964f2a6350Srillig 	/* expect+2: chained assignment with '=' and '=' [Q10] */
3974f2a6350Srillig 	/* expect+1: chained assignment with '=' and '=' [Q10] */
3984f2a6350Srillig 	a = b = c = 0;
3994f2a6350Srillig 
4004f2a6350Srillig 	/* expect+2: chained assignment with '*=' and '-=' [Q10] */
4014f2a6350Srillig 	/* expect+1: chained assignment with '+=' and '*=' [Q10] */
4024f2a6350Srillig 	a += b *= c -= 0;
4034f2a6350Srillig }
4044f2a6350Srillig 
40579e55a0fSrillig void
40679e55a0fSrillig Q11(void)
40779e55a0fSrillig {
40879e55a0fSrillig 	/* expect+1: static variable 'static_var_no_init' in function [Q11] */
40979e55a0fSrillig 	static int static_var_no_init;
41079e55a0fSrillig 	/* expect+1: static variable 'static_var_init' in function [Q11] */
41179e55a0fSrillig 	static int static_var_init = 1;
41279e55a0fSrillig 
41379e55a0fSrillig 	static_var_no_init++;
41479e55a0fSrillig 	static_var_init++;
41579e55a0fSrillig }
41679e55a0fSrillig 
417ec19c40cSrillig void
418ec19c40cSrillig Q12(void)
419ec19c40cSrillig {
420ec19c40cSrillig 	/* expect+1: comma operator with types 'void' and '_Bool' [Q12] */
421ec19c40cSrillig 	if (Q11(), cond)
422ec19c40cSrillig 		return;
423ec19c40cSrillig 
424ec19c40cSrillig 	/* expect+5: implicit conversion changes sign from 'unsigned char' to 'int' [Q3] */
425ec19c40cSrillig 	/* expect+4: implicit conversion changes sign from 'int' to 'unsigned short' [Q3] */
426ec19c40cSrillig 	/* expect+3: implicit conversion changes sign from 'unsigned short' to 'int' [Q3] */
427ec19c40cSrillig 	/* expect+2: implicit conversion changes sign from 'int' to 'unsigned int' [Q3] */
428ec19c40cSrillig 	/* expect+1: comma operator with types 'unsigned short' and 'unsigned int' [Q12] */
429ec19c40cSrillig 	u16 += u8, u32 += u16;
430ec19c40cSrillig }
431ec19c40cSrillig 
4324a6e7880Srillig /* expect+1: redundant 'extern' in function declaration of 'extern_Q13' [Q13] */
4334a6e7880Srillig extern void extern_Q13(void);
4344a6e7880Srillig void extern_Q13(void);
4354a6e7880Srillig /* expect+1: redundant 'extern' in function declaration of 'extern_Q13' [Q13] */
4364a6e7880Srillig extern void extern_Q13(void), *extern_ptr;
4374a6e7880Srillig 
438271d535eSrillig int
4392bb36c11Srillig Q14(signed char sc, unsigned char uc, int wc)
440271d535eSrillig {
4412bb36c11Srillig 	// Plain 'char' is platform-dependent, see queries-{schar,uchar}.c.
4422bb36c11Srillig 
443271d535eSrillig 	if (sc == 'c' || sc == L'w' || sc == 92 || sc == 0)
444271d535eSrillig 		return 2;
445271d535eSrillig 	/* expect+4: implicit conversion changes sign from 'unsigned char' to 'int' [Q3] */
446271d535eSrillig 	/* expect+3: implicit conversion changes sign from 'unsigned char' to 'int' [Q3] */
447271d535eSrillig 	/* expect+2: implicit conversion changes sign from 'unsigned char' to 'int' [Q3] */
448271d535eSrillig 	/* expect+1: implicit conversion changes sign from 'unsigned char' to 'int' [Q3] */
449271d535eSrillig 	if (uc == 'c' || uc == L'w' || uc == 92 || uc == 0)
450271d535eSrillig 		return 3;
451271d535eSrillig 	if (wc == 'c' || wc == L'w' || wc == 92 || wc == 0)
452271d535eSrillig 		return 4;
453271d535eSrillig 	return 5;
454271d535eSrillig }
455271d535eSrillig 
456082684fdSrillig void *
457082684fdSrillig Q15(void)
458082684fdSrillig {
459082684fdSrillig 	/* expect+1: implicit conversion from integer 0 to pointer 'pointer to void' [Q15] */
460082684fdSrillig 	void *ptr_from_int = 0;
461082684fdSrillig 	/* expect+1: implicit conversion from integer 0 to pointer 'pointer to void' [Q15] */
462082684fdSrillig 	void *ptr_from_uint = 0U;
463082684fdSrillig 	/* expect+1: implicit conversion from integer 0 to pointer 'pointer to void' [Q15] */
464082684fdSrillig 	void *ptr_from_long = 0L;
465082684fdSrillig 
466082684fdSrillig 	ptr_from_int = &ptr_from_int;
467082684fdSrillig 	ptr_from_uint = &ptr_from_uint;
468082684fdSrillig 	ptr_from_long = &ptr_from_long;
469082684fdSrillig 
4700382e641Srillig 	void_ptr = (void *)0;
4710382e641Srillig 	const_void_ptr = (const void *)0;
4720382e641Srillig 
473082684fdSrillig 	/* expect+1: implicit conversion from integer 0 to pointer 'pointer to void' [Q15] */
474082684fdSrillig 	return 0;
475082684fdSrillig }
476082684fdSrillig 
477715e58e7Srillig /*
478960c2202Srillig  * Even though C99 6.2.2p4 allows a 'static' declaration followed by a
479960c2202Srillig  * non-'static' declaration, it may look confusing.
480960c2202Srillig  */
481960c2202Srillig static void Q16(void);
48245efdafbSrillig /* expect+3: 'Q16' was declared 'static', now non-'static' [Q16] */
48345efdafbSrillig /* expect+2: warning: static function 'Q16' unused [236] */
48445efdafbSrillig void
48545efdafbSrillig Q16(void)
486960c2202Srillig {
487960c2202Srillig }
488960c2202Srillig 
48974d71898Srillig /* expect+1: invisible character U+0009 in character constant [Q17] */
49074d71898Srillig char Q17_char[] = { ' ', '\0', '	' };
49174d71898Srillig /* expect+1: invisible character U+0009 in string literal [Q17] */
492183f84feSrillig char Q17_char_string[] = " \0	";
493183f84feSrillig /* expect+1: invisible character U+0009 in character constant [Q17] */
494183f84feSrillig int Q17_wide[] = { L' ', L'\0', L'	' };
495183f84feSrillig /* expect+1: invisible character U+0009 in string literal [Q17] */
496183f84feSrillig int Q17_wide_string[] = L" \0	";
49774d71898Srillig 
4987caac601Srillig /* For Q18, see queries_schar.c and queries_uchar.c. */
49945efdafbSrillig 
500370056d3Srillig void
501370056d3Srillig convert_from_integer_to_floating(void)
502370056d3Srillig {
503370056d3Srillig 	/* expect+1: implicit conversion from integer 'unsigned int' to floating point 'float' [Q19] */
504370056d3Srillig 	f32 = 0xffff0000;
505370056d3Srillig 	/* expect+1: implicit conversion from integer 'unsigned int' to floating point 'float' [Q19] */
506370056d3Srillig 	f32 = 0xffffffff;
507370056d3Srillig 	/* expect+1: implicit conversion from integer 'int' to floating point 'float' [Q19] */
508370056d3Srillig 	f32 = s32;
509370056d3Srillig 	/* expect+1: implicit conversion from integer 'unsigned int' to floating point 'float' [Q19] */
510370056d3Srillig 	f32 = u32;
511370056d3Srillig 	/* expect+1: implicit conversion from integer 'int' to floating point 'double' [Q19] */
512370056d3Srillig 	f64 = s32;
513370056d3Srillig 	/* expect+1: implicit conversion from integer 'unsigned int' to floating point 'double' [Q19] */
514370056d3Srillig 	f64 = u32;
515370056d3Srillig 	/* expect+1: implicit conversion from integer 'long long' to floating point 'double' [Q19] */
516370056d3Srillig 	f64 = s64;
517370056d3Srillig 	/* expect+1: implicit conversion from integer 'unsigned long long' to floating point 'double' [Q19] */
518370056d3Srillig 	f64 = u64;
519370056d3Srillig 
520370056d3Srillig 	f32 = 0.0F;
521370056d3Srillig 	f32 = 0.0;
522370056d3Srillig 	f64 = 0.0;
5230382e641Srillig 
5240382e641Srillig 	f64 = (double)0;
5250382e641Srillig 	f64 = (double)u32;
526370056d3Srillig }
527370056d3Srillig 
52896381692Srillig // C allows implicit narrowing conversions from a void pointer to an arbitrary
52996381692Srillig // object pointer. C++ doesn't allow this conversion since it is narrowing.
53096381692Srillig void
53196381692Srillig Q20_void_pointer_conversion(void)
53296381692Srillig {
53388d1eb23Srillig 	/* expect+1: warning: operator '=' discards 'const' from 'pointer to const void' [128] */
53496381692Srillig 	void_ptr = const_void_ptr;
53596381692Srillig 	const_void_ptr = void_ptr;
53696381692Srillig 	/* expect+1: implicit narrowing conversion from void pointer to 'pointer to int' [Q20] */
53796381692Srillig 	int_ptr = void_ptr;
53896381692Srillig 	/* expect+1: redundant cast from 'pointer to void' to 'pointer to int' before assignment [Q7] */
53996381692Srillig 	int_ptr = (int *)void_ptr;
54096381692Srillig 	/* expect+1: implicit narrowing conversion from void pointer to 'pointer to char' [Q20] */
54196381692Srillig 	char_ptr = void_ptr;
54296381692Srillig 	void_ptr = char_ptr;
54396381692Srillig 	/* expect+1: implicit narrowing conversion from void pointer to 'pointer to int' [Q20] */
54496381692Srillig 	int_ptr = void_ptr;
54596381692Srillig 	/* expect+1: warning: illegal combination of 'pointer to int' and 'pointer to char', op '=' [124] */
54696381692Srillig 	int_ptr = char_ptr;
54796381692Srillig 	/* expect+1: warning: illegal combination of 'pointer to char' and 'pointer to int', op '=' [124] */
54896381692Srillig 	char_ptr = int_ptr;
549fc7f5da7Srillig 
550fc7f5da7Srillig 	int_ptr = (void *)0;
55196381692Srillig }
552b2ad51d9Srillig 
553b2ad51d9Srillig /*
554b2ad51d9Srillig  * Q21, Q22, Q23 and Q24 detect typedefs for struct and union types and
555b2ad51d9Srillig  * pointers to them. By using the tagged types directly instead of their
556b2ad51d9Srillig  * typedefs, it may be possible to save including some system headers.
557b2ad51d9Srillig  */
558b2ad51d9Srillig 
559b2ad51d9Srillig struct struct_tag {
560b2ad51d9Srillig };
561b2ad51d9Srillig union union_tag {
562b2ad51d9Srillig };
563b2ad51d9Srillig 
564b2ad51d9Srillig /* expect+2: typedef 'struct_typedef' of struct type 'struct struct_tag' [Q21] */
565b2ad51d9Srillig /* expect+1: typedef 'struct_ptr' of pointer to struct type 'pointer to struct struct_tag' [Q23] */
566b2ad51d9Srillig typedef struct struct_tag struct_typedef, *struct_ptr;
567b2ad51d9Srillig /* expect+2: typedef 'union_typedef' of union type 'union union_tag' [Q22] */
568b2ad51d9Srillig /* expect+1: typedef 'union_ptr' of pointer to union type 'pointer to union union_tag' [Q24] */
569b2ad51d9Srillig typedef union union_tag union_typedef, *union_ptr;
570b2ad51d9Srillig typedef int int_typedef, *int_pointer;
571b2ad51d9Srillig typedef void (function_typedef)(int), (*function_ptr)(int);
572