Skip to content

Commit 12494a4

Browse files
committed
RULE-12-2: Improve reporting
Update the message to include the right operand range in addition to the valid shift range, the essential type of the left operand, and, if relevant, the macro in which the shift is defined.
1 parent 7b73896 commit 12494a4

File tree

2 files changed

+54
-18
lines changed

2 files changed

+54
-18
lines changed

c/misra/src/rules/RULE-12-2/RightHandOperandOfAShiftRange.ql

Lines changed: 42 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,51 @@ class ShiftExpr extends BinaryBitwiseOperation {
2020
ShiftExpr() { this instanceof LShiftExpr or this instanceof RShiftExpr }
2121
}
2222

23-
from ShiftExpr e, Expr right, int max_val
23+
MacroInvocation getAMacroInvocation(ShiftExpr se) { result.getAnExpandedElement() = se }
24+
25+
Macro getPrimaryMacro(ShiftExpr se) {
26+
exists(MacroInvocation mi |
27+
mi = getAMacroInvocation(se) and
28+
not exists(MacroInvocation otherMi |
29+
otherMi = getAMacroInvocation(se) and otherMi.getParentInvocation() = mi
30+
) and
31+
result = mi.getMacro()
32+
)
33+
}
34+
35+
from
36+
ShiftExpr e, Expr right, int max_val, float lowerBound, float upperBound, Type essentialType,
37+
string extraMessage, Locatable optionalPlaceholderLocation, string optionalPlaceholderMessage
2438
where
2539
not isExcluded(right, Contracts7Package::rightHandOperandOfAShiftRangeQuery()) and
2640
right = e.getRightOperand().getFullyConverted() and
27-
max_val = (8 * getEssentialType(e.getLeftOperand()).getSize()) - 1 and
41+
essentialType = getEssentialType(e.getLeftOperand()) and
42+
max_val = (8 * essentialType.getSize()) - 1 and
43+
upperBound = upperBound(right) and
44+
lowerBound = lowerBound(right) and
45+
(
46+
lowerBound < 0 or
47+
upperBound > max_val
48+
) and
49+
// If this shift happens inside a macro, then report the macro as well
50+
// for easier validation
2851
(
29-
lowerBound(right) < 0 or
30-
upperBound(right) > max_val
52+
if exists(getPrimaryMacro(e))
53+
then
54+
extraMessage = " from expansion of macro $@" and
55+
exists(Macro m |
56+
m = getPrimaryMacro(e) and
57+
optionalPlaceholderLocation = m and
58+
optionalPlaceholderMessage = m.getName()
59+
)
60+
else (
61+
extraMessage = "" and
62+
optionalPlaceholderLocation = e and
63+
optionalPlaceholderMessage = ""
64+
)
3165
)
3266
select right,
33-
"The right hand operand of the shift operator shall lie in the range 0 to " + max_val + "."
67+
"The possible range of the right operand of the shift operator (" + lowerBound + ".." + upperBound
68+
+ ") is outside the the valid shift range (0.." + max_val +
69+
") for the essential type of the left operand (" + essentialType + ")" + extraMessage + ".",
70+
optionalPlaceholderLocation, optionalPlaceholderMessage
Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
1-
| test.c:8:10:8:10 | 8 | The right hand operand of the shift operator shall lie in the range 0 to 7. |
2-
| test.c:9:10:9:11 | - ... | The right hand operand of the shift operator shall lie in the range 0 to 7. |
3-
| test.c:10:10:10:14 | ... + ... | The right hand operand of the shift operator shall lie in the range 0 to 7. |
4-
| test.c:11:10:11:14 | ... + ... | The right hand operand of the shift operator shall lie in the range 0 to 7. |
5-
| test.c:13:21:13:22 | 16 | The right hand operand of the shift operator shall lie in the range 0 to 15. |
6-
| test.c:16:9:16:9 | 8 | The right hand operand of the shift operator shall lie in the range 0 to 7. |
7-
| test.c:21:9:21:10 | 64 | The right hand operand of the shift operator shall lie in the range 0 to 63. |
8-
| test.c:25:10:25:10 | 8 | The right hand operand of the shift operator shall lie in the range 0 to 7. |
9-
| test.c:26:10:26:11 | 64 | The right hand operand of the shift operator shall lie in the range 0 to 7. |
10-
| test.c:30:16:30:17 | 64 | The right hand operand of the shift operator shall lie in the range 0 to 63. |
11-
| test.c:34:8:34:8 | y | The right hand operand of the shift operator shall lie in the range 0 to 31. |
12-
| test.c:40:8:40:8 | y | The right hand operand of the shift operator shall lie in the range 0 to 31. |
13-
| test.c:42:8:42:8 | y | The right hand operand of the shift operator shall lie in the range 0 to 31. |
1+
| test.c:8:10:8:10 | 8 | The possible range of the right operand of the shift operator (8..8) is outside the the valid shift range (0..7) for the essential type of the left operand (uint8_t). | test.c:8:3:8:10 | ... >> ... | |
2+
| test.c:9:10:9:11 | - ... | The possible range of the right operand of the shift operator (-1..-1) is outside the the valid shift range (0..7) for the essential type of the left operand (uint8_t). | test.c:9:3:9:11 | ... >> ... | |
3+
| test.c:10:10:10:14 | ... + ... | The possible range of the right operand of the shift operator (8..8) is outside the the valid shift range (0..7) for the essential type of the left operand (uint8_t). | test.c:10:3:10:14 | ... >> ... | |
4+
| test.c:11:10:11:14 | ... + ... | The possible range of the right operand of the shift operator (8..8) is outside the the valid shift range (0..7) for the essential type of the left operand (uint8_t). | test.c:11:3:11:14 | ... << ... | |
5+
| test.c:13:21:13:22 | 16 | The possible range of the right operand of the shift operator (16..16) is outside the the valid shift range (0..15) for the essential type of the left operand (uint16_t). | test.c:13:3:13:22 | ... << ... | |
6+
| test.c:16:9:16:9 | 8 | The possible range of the right operand of the shift operator (8..8) is outside the the valid shift range (0..7) for the essential type of the left operand (unsigned char). | test.c:16:3:16:9 | ... << ... | |
7+
| test.c:21:9:21:10 | 64 | The possible range of the right operand of the shift operator (64..64) is outside the the valid shift range (0..63) for the essential type of the left operand (unsigned long). | test.c:21:3:21:10 | ... << ... | |
8+
| test.c:26:10:26:11 | 64 | The possible range of the right operand of the shift operator (64..64) is outside the the valid shift range (0..63) for the essential type of the left operand (unsigned long). | test.c:26:3:26:11 | ... << ... | |
9+
| test.c:30:16:30:17 | 64 | The possible range of the right operand of the shift operator (64..64) is outside the the valid shift range (0..63) for the essential type of the left operand (unsigned long). | test.c:30:3:30:17 | ... << ... | |
10+
| test.c:34:8:34:8 | y | The possible range of the right operand of the shift operator (0..4294967295) is outside the the valid shift range (0..31) for the essential type of the left operand (unsigned int). | test.c:34:3:34:8 | ... >> ... | |
11+
| test.c:40:8:40:8 | y | The possible range of the right operand of the shift operator (-2147483648..2147483647) is outside the the valid shift range (0..31) for the essential type of the left operand (signed int). | test.c:40:3:40:8 | ... >> ... | |
12+
| test.c:42:8:42:8 | y | The possible range of the right operand of the shift operator (-31..31) is outside the the valid shift range (0..31) for the essential type of the left operand (signed int). | test.c:42:3:42:8 | ... >> ... | |

0 commit comments

Comments
 (0)