queries.c revision 1.1 1 /* $NetBSD: queries.c,v 1.1 2022/07/05 22:50:41 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 int
21 Q1(double dbl)
22 {
23 /* expect+1: implicit conversion from floating point 'double' to integer 'int' [Q1] */
24 return dbl;
25 }
26
27 int
28 Q2(double dbl)
29 {
30 /* expect+2: cast from floating point 'double' to integer 'int' [Q2] */
31 /* expect+1: redundant cast from 'double' to 'int' before assignment [Q7] */
32 return (int)dbl;
33 }
34
35 void
36 Q3(int i, unsigned u)
37 {
38 /* expect+1: implicit conversion changes sign from 'int' to 'unsigned int' [Q3] */
39 u = i;
40
41 /* expect+1: implicit conversion changes sign from 'unsigned int' to 'int' [Q3] */
42 i = u;
43 }
44
45 unsigned long long
46 Q4(char *ptr, int i, unsigned long long ull)
47 {
48 /*
49 * The conversion from 'char' to 'int' is done by the integer
50 * promotions (C11 6.3.1.1p2), not by the usual arithmetic
51 * conversions (C11 6.3.1.8p1).
52 */
53 /* expect+2: usual arithmetic conversion for '+' from 'int' to 'unsigned long long' [Q4] */
54 /* expect+1: implicit conversion changes sign from 'int' to 'unsigned long long' [Q3] */
55 return ptr[0] + ptr[1] + i + ull;
56 }
57
58 void
59 Q5(char *ptr, int i)
60 {
61 if (ptr + i > ptr)
62 return;
63
64 /* expect+1: pointer addition has integer on the left-hand side [Q5] */
65 if (i + ptr > ptr)
66 return;
67
68 if (ptr[i] != '\0')
69 return;
70
71 /* expect+1: pointer addition has integer on the left-hand side [Q5] */
72 if (i[ptr] != '\0')
73 return;
74 }
75
76 void
77 Q6(int i)
78 {
79 /* expect+1: no-op cast from 'int' to 'int' [Q6] */
80 i = (int)4;
81
82 /* expect+1: no-op cast from 'int' to 'int' [Q6] */
83 i = (int)i + 1;
84 }
85
86 extern void *allocate(unsigned long);
87
88 char *
89 Q7(void)
90 {
91 /* expect+1: redundant cast from 'pointer to void' to 'pointer to char' before assignment [Q7] */
92 char *str = (char *)allocate(64);
93
94 if (str == (void *)0)
95 /* expect+1: redundant cast from 'pointer to void' to 'pointer to char' before assignment [Q7] */
96 str = (char *)allocate(64);
97
98 return str;
99 }
100
101
102 /*
103 * Since queries do not affect the exit status, force a warning to make this
104 * test conform to the general expectation that a test that produces output
105 * exits non-successfully.
106 */
107 /* expect+1: warning: static variable 'unused' unused [226] */
108 static int unused;
109