Skip to content

Commit 916df88

Browse files
committed
RULE 11.4: Improve reporting
Improve the message by (a) reporting which order the cast is (b) what the actual types are (c) by providing a link to the macro invocation if the cast is created by a function like macro
1 parent 5ad86ef commit 916df88

File tree

3 files changed

+69
-15
lines changed

3 files changed

+69
-15
lines changed

c/misra/src/rules/RULE-11-4/ConversionBetweenPointerToObjectAndIntegerType.ql

Lines changed: 51 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -24,23 +24,62 @@ Macro getPrimaryMacro(CStyleCast cast) {
2424
not exists(MacroInvocation otherMi |
2525
otherMi = getAMacroInvocation(cast) and otherMi.getParentInvocation() = mi
2626
) and
27-
result = mi.getMacro() and
28-
not result instanceof FunctionLikeMacro
27+
result = mi.getMacro()
2928
)
3029
}
3130

32-
from Locatable primaryLocation, CStyleCast cast, Type typeFrom, Type typeTo
31+
Macro getNonFunctionPrimaryMacro(CStyleCast cast) {
32+
result = getPrimaryMacro(cast) and
33+
not result instanceof FunctionLikeMacro
34+
}
35+
36+
from
37+
Locatable primaryLocation, CStyleCast cast, Type typeFrom, Type typeTo, string message,
38+
string extraMessage, Locatable optionalPlaceholderLocation, string optionalPlaceholderMessage
3339
where
3440
not isExcluded(cast, Pointers1Package::castBetweenObjectPointerAndDifferentObjectTypeQuery()) and
3541
typeFrom = cast.getExpr().getUnderlyingType() and
3642
typeTo = cast.getUnderlyingType() and
37-
[typeFrom, typeTo] instanceof IntegralType and
38-
[typeFrom, typeTo] instanceof PointerToObjectType and
43+
(
44+
typeFrom instanceof PointerToObjectType and
45+
typeTo instanceof IntegralType and
46+
message =
47+
"Cast from pointer to object type '" + typeFrom + "' to integer type '" + typeTo + "'" +
48+
extraMessage + "."
49+
or
50+
typeFrom instanceof IntegralType and
51+
typeTo instanceof PointerToObjectType and
52+
message =
53+
"Cast from integer type '" + typeFrom + "' to pointer to object type '" + typeTo + "'" +
54+
extraMessage + "."
55+
) and
3956
not isNullPointerConstant(cast.getExpr()) and
40-
// If this alert is arising through a macro expansion, flag the macro instead, to
41-
// help make the alerts more manageable
42-
if exists(getPrimaryMacro(cast))
43-
then primaryLocation = getPrimaryMacro(cast)
44-
else primaryLocation = cast
45-
select primaryLocation,
46-
"Cast performed between a pointer to object type and a pointer to an integer type."
57+
// If this alert is arising through a non-function-like macro expansion, flag the macro instead, to
58+
// help make the alerts more manageable. We only do this for non-function-like macros because they
59+
// cannot be context specific.
60+
if exists(getNonFunctionPrimaryMacro(cast))
61+
then
62+
primaryLocation = getNonFunctionPrimaryMacro(cast) and
63+
extraMessage = "" and
64+
optionalPlaceholderLocation = primaryLocation and
65+
optionalPlaceholderMessage = ""
66+
else (
67+
primaryLocation = cast and
68+
// If the cast is in a macro expansion which is context specific, we still report the original
69+
// location, but also add a link to the most specific macro that contains the cast, to aid
70+
// validation.
71+
if exists(getPrimaryMacro(cast))
72+
then
73+
extraMessage = " from expansion of macro $@" and
74+
exists(Macro m |
75+
m = getPrimaryMacro(cast) and
76+
optionalPlaceholderLocation = m and
77+
optionalPlaceholderMessage = m.getName()
78+
)
79+
else (
80+
extraMessage = "" and
81+
optionalPlaceholderLocation = cast and
82+
optionalPlaceholderMessage = ""
83+
)
84+
)
85+
select primaryLocation, message, optionalPlaceholderLocation, optionalPlaceholderMessage
Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1-
| test.c:6:21:6:37 | (unsigned int)... | Cast performed between a pointer to object type and a pointer to an integer type. |
2-
| test.c:8:8:8:24 | (unsigned int)... | Cast performed between a pointer to object type and a pointer to an integer type. |
3-
| test.c:12:22:12:39 | (unsigned int *)... | Cast performed between a pointer to object type and a pointer to an integer type. |
1+
| test.c:6:21:6:37 | (unsigned int)... | Cast from pointer to object type 'unsigned int *' to integer type 'unsigned int'. | test.c:6:21:6:37 | (unsigned int)... | |
2+
| test.c:8:8:8:24 | (unsigned int)... | Cast from pointer to object type 'unsigned int *' to integer type 'unsigned int'. | test.c:8:8:8:24 | (unsigned int)... | |
3+
| test.c:12:22:12:39 | (unsigned int *)... | Cast from integer type 'unsigned int' to pointer to object type 'unsigned int *'. | test.c:12:22:12:39 | (unsigned int *)... | |
4+
| test.c:15:1:15:24 | #define FOO (int *)0x200 | Cast from integer type 'int' to pointer to object type 'int *'. | test.c:15:1:15:24 | #define FOO (int *)0x200 | |
5+
| test.c:23:3:23:22 | (int *)... | Cast from integer type 'int' to pointer to object type 'int *' from expansion of macro $@. | test.c:17:1:17:34 | #define FOO_FUNCTIONAL(x) (int *)x | FOO_FUNCTIONAL |
6+
| test.c:24:14:24:25 | (int *)... | Cast from integer type 'int' to pointer to object type 'int *' from expansion of macro $@. | test.c:18:1:18:23 | #define FOO_INSERT(x) x | FOO_INSERT |

c/misra/test/rules/RULE-11-4/test.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,16 @@ void f1(void) {
1010
unsigned int *v4 = 0; // COMPLIANT
1111
unsigned int *v5 = NULL; // COMPLIANT
1212
unsigned int *v6 = (unsigned int *)v2; // NON_COMPLIANT
13+
}
14+
15+
#define FOO (int *)0x200 // NON_COMPLIANT
16+
#define FOO_WRAPPER FOO;
17+
#define FOO_FUNCTIONAL(x) (int *)x
18+
#define FOO_INSERT(x) x
19+
20+
void test_macros() {
21+
FOO; // Issue is reported at the macro
22+
FOO_WRAPPER; // Issue is reported at the macro
23+
FOO_FUNCTIONAL(0x200); // NON_COMPLIANT
24+
FOO_INSERT((int *)0x200); // NON_COMPLIANT
1325
}

0 commit comments

Comments
 (0)