Skip to content

Commit 6e6250f

Browse files
authored
Merge branch 'main' into lcartey/rule-11-4-improvements
2 parents bf1c4ce + fb43031 commit 6e6250f

File tree

15 files changed

+350
-66
lines changed

15 files changed

+350
-66
lines changed

c/misra/src/rules/RULE-7-2/UOrUSuffixRepresentedInUnsignedType.ql

+10-3
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,13 @@ from Literal l
1919
where
2020
not isExcluded(l, SyntaxPackage::uOrUSuffixRepresentedInUnsignedTypeQuery()) and
2121
not l instanceof StringLiteral and
22-
l.getImplicitlyConverted().getType().(IntegralType).isUnsigned() and
23-
not exists(l.getValueText().toUpperCase().indexOf("U"))
24-
select l, "Unsigned literal does not explicitly express sign with a 'U' or 'u' suffix."
22+
// Determine if the extractor deduced that the literal is unsigned, based on the C rules
23+
l.getType().(IntegralType).isUnsigned() and
24+
// And report if the literal does not contain a 'U' or 'u' suffix, e.g. explicitly unsigned
25+
not exists(l.getValueText().toUpperCase().indexOf("U")) and
26+
// Exclude constants generated by macro expansions, because the suffix information is lost in this
27+
// case, so can cause false positives.
28+
not l.isInMacroExpansion()
29+
select l,
30+
"Unsigned literal " + l.getValueText() +
31+
" does not explicitly express sign with a 'U' or 'u' suffix."

c/misra/src/rules/RULE-8-3/DeclarationsOfAnObjectSameNameAndType.ql

+12
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,19 @@ where
2121
not isExcluded(decl2, Declarations4Package::declarationsOfAnObjectSameNameAndTypeQuery()) and
2222
not decl1 = decl2 and
2323
not decl1.getVariable().getDeclaringType().isAnonymous() and
24+
// Declarations are for the same qualified name
25+
// Note: decl1.getVariable() = decl2.getVariable() does not work for common cases where an aliased
26+
// type is used.
2427
decl1.getVariable().getQualifiedName() = decl2.getVariable().getQualifiedName() and
28+
// As we use qualified name, require that they share a common link target to ensure they are
29+
// for the same object
30+
(
31+
decl1.getVariable().(GlobalVariable).getALinkTarget() =
32+
decl2.getVariable().(GlobalVariable).getALinkTarget()
33+
or
34+
decl1.getVariable().(Field).getDeclaringType().(Class).getALinkTarget() =
35+
decl2.getVariable().(Field).getDeclaringType().(Class).getALinkTarget()
36+
) and
2537
not typesCompatible(decl1.getType(), decl2.getType())
2638
select decl1,
2739
"The object $@ of type " + decl1.getType().toString() +
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
| test.c:8:20:8:21 | 0 | Unsigned literal does not explicitly express sign with a 'U' or 'u' suffix. |
2-
| test.c:9:20:9:22 | 0 | Unsigned literal does not explicitly express sign with a 'U' or 'u' suffix. |
3-
| test.c:33:6:33:6 | 1 | Unsigned literal does not explicitly express sign with a 'U' or 'u' suffix. |
4-
| test.c:35:6:35:9 | 1 | Unsigned literal does not explicitly express sign with a 'U' or 'u' suffix. |
5-
| test.c:37:6:37:8 | 1 | Unsigned literal does not explicitly express sign with a 'U' or 'u' suffix. |
1+
| test.c:111:3:111:12 | 2147483648 | Unsigned literal 0x80000000 does not explicitly express sign with a 'U' or 'u' suffix. |
2+
| test.c:116:3:116:20 | 9223372036854775808 | Unsigned literal 0x8000000000000000 does not explicitly express sign with a 'U' or 'u' suffix. |
3+
| test.c:139:3:139:21 | 9223372036854775808 | Unsigned literal 0x8000000000000000l does not explicitly express sign with a 'U' or 'u' suffix. |
4+
| test.c:162:3:162:21 | 9223372036854775808 | Unsigned literal 0x8000000000000000L does not explicitly express sign with a 'U' or 'u' suffix. |
5+
| test.c:185:3:185:22 | 9223372036854775808 | Unsigned literal 0x8000000000000000ll does not explicitly express sign with a 'U' or 'u' suffix. |
6+
| test.c:208:3:208:22 | 9223372036854775808 | Unsigned literal 0x8000000000000000LL does not explicitly express sign with a 'U' or 'u' suffix. |

c/misra/test/rules/RULE-7-2/test.c

+229-37
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,231 @@
1+
// Assumed platform in qltest is linux_x86_64, so
2+
// int, long, long long sizes are assumed to be 32, 64, 64 bits respectively
13

2-
long a1 = 0L; // COMPLIANT
3-
long a2 = 0LL; // COMPLIANT
4-
long a3 = 0uL; // COMPLIANT
5-
long a4 = 0Lu; // COMPLIANT
6-
long a5 = 0LU; // COMPLIANT
7-
8-
unsigned long b1 = 0L; // NON_COMPLIANT
9-
unsigned long b2 = 0LL; // NON_COMPLIANT
10-
unsigned long b3 = 0uL; // COMPLIANT
11-
unsigned long b4 = 0Lu; // COMPLIANT
12-
unsigned long b5 = 0LU; // COMPLIANT
13-
14-
signed long c1 = 0L; // COMPLIANT
15-
signed long c2 = 0LL; // COMPLIANT
16-
signed long c3 = 0uL; // COMPLIANT
17-
signed long c4 = 0Lu; // COMPLIANT
18-
signed long c5 = 0LU; // COMPLIANT
19-
20-
void f0(int a) {}
21-
22-
void f1(unsigned int a) {}
23-
24-
void f2() {
25-
26-
f0(1); // COMPLIANT
27-
f0(1U); // COMPLIANT
28-
f0(0x01); // COMPLIANT
29-
f0(0x01U); // COMPLIANT
30-
f0(001); // COMPLIANT
31-
f0(001U); // COMPLIANT
32-
33-
f1(1); // NON_COMPLIANT
34-
f1(1U); // COMPLIANT
35-
f1(0x01); // NON_COMPLIANT
36-
f1(0x01U); // COMPLIANT
37-
f1(001); // NON_COMPLIANT
38-
f1(001U); // COMPLIANT
4+
// The type of an integer constant is determined by "6.4.4.1 Integer constants"
5+
// in the C11 Standard. The principle is that any decimal integer constant will
6+
// be signed, unless it has the `U` or `u` suffix. Any hexadecimal integer will
7+
// depend on whether it is larger than the maximum value of the smallest signed
8+
// integer value that can hold the value. So the signedness depends on the
9+
// magnitude of the constant.
10+
11+
void test_decimal_constants() {
12+
0; // COMPLIANT
13+
2147483648; // COMPLIANT - larger than int, but decimal constants never use
14+
// unsigned without the suffix, so will be `long`
15+
4294967296; // COMPLIANT - larger than unsigned int, still `long`
16+
9223372036854775807; // COMPLIANT - max long int
17+
// 9223372036854775808; Not a valid integer constant, out of signed range
18+
0U; // COMPLIANT - unsigned, but uses the suffix correctly
19+
2147483648U; // COMPLIANT - unsigned, but uses the suffix correctly
20+
4294967296U; // COMPLIANT - unsigned, but uses the suffix correctly
21+
9223372036854775807U; // COMPLIANT - max long int
22+
9223372036854775808U; // COMPLIANT - explicitly unsigned, so can go large than
23+
// max long int
24+
0u; // COMPLIANT - unsigned, but uses the suffix correctly
25+
2147483648u; // COMPLIANT - unsigned, but uses the suffix correctly
26+
4294967296u; // COMPLIANT - unsigned, but uses the suffix correctly
27+
9223372036854775807u; // COMPLIANT - max long int
28+
9223372036854775808u; // COMPLIANT - explicitly unsigned, so can go large than
29+
// max long int
30+
31+
// l suffix
32+
0l; // COMPLIANT
33+
2147483648l; // COMPLIANT - within the range of long int
34+
4294967296l; // COMPLIANT - within the range of long int
35+
9223372036854775807l; // COMPLIANT - max long int
36+
// 9223372036854775808l; Not a valid integer constant, out of signed range
37+
0lU; // COMPLIANT - unsigned, but uses the suffix correctly
38+
2147483648lU; // COMPLIANT - unsigned, but uses the suffix correctly
39+
4294967296lU; // COMPLIANT - unsigned, but uses the suffix correctly
40+
9223372036854775807lU; // COMPLIANT - max long int
41+
9223372036854775808lU; // COMPLIANT - explicitly unsigned, so can go large
42+
// than max long int
43+
0lu; // COMPLIANT - unsigned, but uses the suffix correctly
44+
2147483648lu; // COMPLIANT - unsigned, but uses the suffix correctly
45+
4294967296lu; // COMPLIANT - unsigned, but uses the suffix correctly
46+
9223372036854775807lu; // COMPLIANT - max long int
47+
9223372036854775808lu; // COMPLIANT - explicitly unsigned, so can go large
48+
// than max long int
49+
50+
// L suffix
51+
0L; // COMPLIANT
52+
2147483648L; // COMPLIANT - within the range of long int
53+
4294967296L; // COMPLIANT - within the range of long int
54+
9223372036854775807L; // COMPLIANT - max long int
55+
// 9223372036854775808L; Not a valid integer constant, out of signed range
56+
0LU; // COMPLIANT - unsigned, but uses the suffix correctly
57+
2147483648LU; // COMPLIANT - unsigned, but uses the suffix correctly
58+
4294967296LU; // COMPLIANT - unsigned, but uses the suffix correctly
59+
9223372036854775807LU; // COMPLIANT - max long int
60+
9223372036854775808LU; // COMPLIANT - explicitly unsigned, so can go large
61+
// than max long int
62+
0Lu; // COMPLIANT - unsigned, but uses the suffix correctly
63+
2147483648Lu; // COMPLIANT - unsigned, but uses the suffix correctly
64+
4294967296Lu; // COMPLIANT - unsigned, but uses the suffix correctly
65+
9223372036854775807Lu; // COMPLIANT - max long int
66+
9223372036854775808Lu; // COMPLIANT - explicitly unsigned, so can go large
67+
// than max long int
68+
69+
// ll suffix
70+
0ll; // COMPLIANT
71+
2147483648ll; // COMPLIANT - within the range of long long int
72+
4294967296ll; // COMPLIANT - within the range of long long int
73+
9223372036854775807ll; // COMPLIANT - max long long int
74+
// 9223372036854775808ll; Not a valid integer constant, out of signed range
75+
0llU; // COMPLIANT - unsigned, but uses the suffix correctly
76+
2147483648llU; // COMPLIANT - unsigned, but uses the suffix correctly
77+
4294967296llU; // COMPLIANT - unsigned, but uses the suffix correctly
78+
9223372036854775807llU; // COMPLIANT - max long long int
79+
9223372036854775808llU; // COMPLIANT - explicitly unsigned, so can go large
80+
// than max long long int
81+
0llu; // COMPLIANT - unsigned, but uses the suffix correctly
82+
2147483648llu; // COMPLIANT - unsigned, but uses the suffix correctly
83+
4294967296llu; // COMPLIANT - unsigned, but uses the suffix correctly
84+
9223372036854775807llu; // COMPLIANT - max long long int
85+
9223372036854775808llu; // COMPLIANT - explicitly unsigned, so can go large
86+
// than max long long int
87+
88+
// LL suffix
89+
0LL; // COMPLIANT
90+
2147483648LL; // COMPLIANT - within the range of long long int
91+
4294967296LL; // COMPLIANT - within the range of long long int
92+
9223372036854775807LL; // COMPLIANT - max long long int
93+
// 9223372036854775808LL; Not a valid integer constant, out of signed range
94+
0LLU; // COMPLIANT - unsigned, but uses the suffix correctly
95+
2147483648LLU; // COMPLIANT - unsigned, but uses the suffix correctly
96+
4294967296LLU; // COMPLIANT - unsigned, but uses the suffix correctly
97+
9223372036854775807LLU; // COMPLIANT - max long long int
98+
9223372036854775808LLU; // COMPLIANT - explicitly unsigned, so can go large
99+
// than max long long int
100+
0LLu; // COMPLIANT - unsigned, but uses the suffix correctly
101+
2147483648LLu; // COMPLIANT - unsigned, but uses the suffix correctly
102+
4294967296LLu; // COMPLIANT - unsigned, but uses the suffix correctly
103+
9223372036854775807LLu; // COMPLIANT - max long long int
104+
9223372036854775808LLu; // COMPLIANT - explicitly unsigned, so can go large
105+
// than max long long int
39106
}
107+
108+
void test_hexadecimal_constants() {
109+
0x0; // COMPLIANT - uses signed int
110+
0x7FFFFFFF; // COMPLIANT - max value held by signed int
111+
0x80000000; // NON_COMPLIANT - larger than max signed int, so will be unsigned
112+
// int
113+
0x100000000; // COMPLIANT - larger than unsigned int, but smaller than long
114+
// int
115+
0x7FFFFFFFFFFFFFFF; // COMPLIANT - max long int
116+
0x8000000000000000; // NON_COMPLIANT - larger than long int, so will be
117+
// unsigned long int
118+
0x0U; // COMPLIANT - unsigned, but uses the suffix correctly
119+
0x7FFFFFFFU; // COMPLIANT - unsigned, but uses the suffix correctly
120+
0x80000000U; // COMPLIANT - unsigned, but uses the suffix correctly
121+
0x100000000U; // COMPLIANT - unsigned, but uses the suffix correctly
122+
0x7FFFFFFFFFFFFFFFU; // COMPLIANT - unsigned, but uses the suffix correctly
123+
0x8000000000000000U; // COMPLIANT - unsigned, but uses the suffix correctly
124+
0x0u; // COMPLIANT - unsigned, but uses the suffix correctly
125+
0x7FFFFFFFu; // COMPLIANT - unsigned, but uses the suffix correctly
126+
0x80000000u; // COMPLIANT - unsigned, but uses the suffix correctly
127+
0x100000000u; // COMPLIANT - unsigned, but uses the suffix correctly
128+
0x7FFFFFFFFFFFFFFFu; // COMPLIANT - unsigned, but uses the suffix correctly
129+
0x8000000000000000u; // COMPLIANT - unsigned, but uses the suffix correctly
130+
131+
// Use of the `l` suffix
132+
0x0l; // COMPLIANT - uses signed int
133+
0x7FFFFFFFl; // COMPLIANT - max value held by signed int
134+
0x80000000l; // COMPLIANT - larger than max signed int, but smaller than long
135+
// int
136+
0x100000000l; // COMPLIANT - larger than unsigned int, but smaller than long
137+
// int
138+
0x7FFFFFFFFFFFFFFFl; // COMPLIANT - max long int
139+
0x8000000000000000l; // NON_COMPLIANT - larger than long int, so will be
140+
// unsigned long int
141+
0x0lU; // COMPLIANT - unsigned, but uses the suffix correctly
142+
0x7FFFFFFFlU; // COMPLIANT - unsigned, but uses the suffix correctly
143+
0x80000000lU; // COMPLIANT - unsigned, but uses the suffix correctly
144+
0x100000000lU; // COMPLIANT - unsigned, but uses the suffix correctly
145+
0x7FFFFFFFFFFFFFFFlU; // COMPLIANT - unsigned, but uses the suffix correctly
146+
0x8000000000000000lU; // COMPLIANT - unsigned, but uses the suffix correctly
147+
0x0lu; // COMPLIANT - unsigned, but uses the suffix correctly
148+
0x7FFFFFFFlu; // COMPLIANT - unsigned, but uses the suffix correctly
149+
0x80000000lu; // COMPLIANT - unsigned, but uses the suffix correctly
150+
0x100000000lu; // COMPLIANT - unsigned, but uses the suffix correctly
151+
0x7FFFFFFFFFFFFFFFlu; // COMPLIANT - unsigned, but uses the suffix correctly
152+
0x8000000000000000lu; // COMPLIANT - unsigned, but uses the suffix correctly
153+
154+
// Use of the `L` suffix
155+
0x0L; // COMPLIANT - uses signed int
156+
0x7FFFFFFFL; // COMPLIANT - max value held by signed int
157+
0x80000000L; // COMPLIANT - larger than max signed int, but smaller than long
158+
// int
159+
0x100000000L; // COMPLIANT - larger than unsigned int, but smaller than long
160+
// int
161+
0x7FFFFFFFFFFFFFFFL; // COMPLIANT - max long int
162+
0x8000000000000000L; // NON_COMPLIANT - larger than long int, so will be
163+
// unsigned long int
164+
0x0LU; // COMPLIANT - unsigned, but uses the suffix correctly
165+
0x7FFFFFFFLU; // COMPLIANT - unsigned, but uses the suffix correctly
166+
0x80000000LU; // COMPLIANT - unsigned, but uses the suffix correctly
167+
0x100000000LU; // COMPLIANT - unsigned, but uses the suffix correctly
168+
0x7FFFFFFFFFFFFFFFLU; // COMPLIANT - unsigned, but uses the suffix correctly
169+
0x8000000000000000LU; // COMPLIANT - unsigned, but uses the suffix correctly
170+
0x0Lu; // COMPLIANT - unsigned, but uses the suffix correctly
171+
0x7FFFFFFFLu; // COMPLIANT - unsigned, but uses the suffix correctly
172+
0x80000000Lu; // COMPLIANT - unsigned, but uses the suffix correctly
173+
0x100000000Lu; // COMPLIANT - unsigned, but uses the suffix correctly
174+
0x7FFFFFFFFFFFFFFFLu; // COMPLIANT - unsigned, but uses the suffix correctly
175+
0x8000000000000000Lu; // COMPLIANT - unsigned, but uses the suffix correctly
176+
177+
// Use of the `ll` suffix
178+
0x0ll; // COMPLIANT - uses signed int
179+
0x7FFFFFFFll; // COMPLIANT - max value held by signed int
180+
0x80000000ll; // COMPLIANT - larger than max signed int, but smaller than long
181+
// long int
182+
0x100000000ll; // COMPLIANT - larger than unsigned int, but smaller than long
183+
// long int
184+
0x7FFFFFFFFFFFFFFFll; // COMPLIANT - max long long int
185+
0x8000000000000000ll; // NON_COMPLIANT - larger than long long int, so will be
186+
// unsigned long long int
187+
0x0llU; // COMPLIANT - unsigned, but uses the suffix correctly
188+
0x7FFFFFFFllU; // COMPLIANT - unsigned, but uses the suffix correctly
189+
0x80000000llU; // COMPLIANT - unsigned, but uses the suffix correctly
190+
0x100000000llU; // COMPLIANT - unsigned, but uses the suffix correctly
191+
0x7FFFFFFFFFFFFFFFllU; // COMPLIANT - unsigned, but uses the suffix correctly
192+
0x8000000000000000llU; // COMPLIANT - unsigned, but uses the suffix correctly
193+
0x0llu; // COMPLIANT - unsigned, but uses the suffix correctly
194+
0x7FFFFFFFllu; // COMPLIANT - unsigned, but uses the suffix correctly
195+
0x80000000llu; // COMPLIANT - unsigned, but uses the suffix correctly
196+
0x100000000llu; // COMPLIANT - unsigned, but uses the suffix correctly
197+
0x7FFFFFFFFFFFFFFFllu; // COMPLIANT - unsigned, but uses the suffix correctly
198+
0x8000000000000000llu; // COMPLIANT - unsigned, but uses the suffix correctly
199+
200+
// Use of the `LL` suffix
201+
0x0LL; // COMPLIANT - uses signed int
202+
0x7FFFFFFFLL; // COMPLIANT - max value held by signed int
203+
0x80000000LL; // COMPLIANT - larger than max signed int, but smaller than long
204+
// long int
205+
0x100000000LL; // COMPLIANT - larger than unsigned int, but smaller than long
206+
// long int
207+
0x7FFFFFFFFFFFFFFFLL; // COMPLIANT - max long long int
208+
0x8000000000000000LL; // NON_COMPLIANT - larger than long long int, so will be
209+
// unsigned long long int
210+
0x0LLU; // COMPLIANT - unsigned, but uses the suffix correctly
211+
0x7FFFFFFFLLU; // COMPLIANT - unsigned, but uses the suffix correctly
212+
0x80000000LLU; // COMPLIANT - unsigned, but uses the suffix correctly
213+
0x100000000LLU; // COMPLIANT - unsigned, but uses the suffix correctly
214+
0x7FFFFFFFFFFFFFFFLLU; // COMPLIANT - unsigned, but uses the suffix correctly
215+
0x8000000000000000LLU; // COMPLIANT - unsigned, but uses the suffix correctly
216+
0x0LLu; // COMPLIANT - unsigned, but uses the suffix correctly
217+
0x7FFFFFFFLLu; // COMPLIANT - unsigned, but uses the suffix correctly
218+
0x80000000LLu; // COMPLIANT - unsigned, but uses the suffix correctly
219+
0x100000000LLu; // COMPLIANT - unsigned, but uses the suffix correctly
220+
0x7FFFFFFFFFFFFFFFLLu; // COMPLIANT - unsigned, but uses the suffix correctly
221+
0x8000000000000000LLu; // COMPLIANT - unsigned, but uses the suffix correctly
222+
}
223+
224+
#define COMPLIANT_VAL 0x80000000U
225+
#define NON_COMPLIANT_VAL 0x80000000
226+
227+
void test_macro() {
228+
COMPLIANT_VAL; // COMPLIANT
229+
NON_COMPLIANT_VAL; // NON_COMPLIANT[FALSE_NEGATIVE] - cannot determine suffix
230+
// in macro expansions
231+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
- `M0-1-9` - `DeadCode.qll`:
2+
- Fixes #678. Remove dead code false positive when integer constant expression is used to define the size of an array.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
- `RULE-8-3` - `DeclarationsOfAnObjectSameNameAndType.ql`
2+
- Remove false positives where two conflicting declarations are never linked together.
+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
- `RULE-7-2` - `UOrUSuffixRepresentedInUnsignedType.ql`
2+
- Remove false positives where integer constants are generated from macros.
3+
- Remove false positives where a signed integer is implicitly converted to unsigned, which is permitted by the standard.

0 commit comments

Comments
 (0)