Skip to content

Commit 3fc1125

Browse files
committed
RULE-12-2
1 parent 82c3013 commit 3fc1125

File tree

4 files changed

+65
-0
lines changed

4 files changed

+65
-0
lines changed
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/**
2+
* @id c/misra/right-hand-operand-of-a-shift-range
3+
* @name RULE-12-2: The right operand of a shift shall be smaller then the width in bits of the left operand
4+
* @description The right hand operand of a shift operator shall lie in the range zero to one less
5+
* than the width in bits of the essential type of the left hand operand
6+
* @kind problem
7+
* @precision very-high
8+
* @problem.severity error
9+
* @tags external/misra/id/rule-12-2
10+
* correctness
11+
* external/misra/obligation/required
12+
*/
13+
14+
import cpp
15+
import codingstandards.c.misra
16+
import codingstandards.c.misra.EssentialTypes
17+
import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis
18+
19+
class ShiftExpr extends BinaryBitwiseOperation {
20+
ShiftExpr() { this instanceof LShiftExpr or this instanceof RShiftExpr }
21+
}
22+
23+
from ShiftExpr e, Expr right, int max_val
24+
where
25+
not isExcluded(right, Contracts7Package::rightHandOperandOfAShiftRangeQuery()) and
26+
right = e.getRightOperand().getFullyConverted() and
27+
max_val = (8 * getEssentialType(e.getLeftOperand()).getSize()) - 1 and
28+
(
29+
lowerBound(right) < 0 or
30+
upperBound(right) > max_val
31+
)
32+
select right, "The shift right hand operand shall lie in the range 0 to " + max_val + "."
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
| test.c:8:10:8:10 | 8 | The shift right hand operand shall lie in the range 0 to 7. |
2+
| test.c:10:10:10:14 | ... + ... | The shift right hand operand shall lie in the range 0 to 7. |
3+
| test.c:11:10:11:14 | ... + ... | The shift right hand operand shall lie in the range 0 to 7. |
4+
| test.c:15:9:15:9 | 8 | The shift right hand operand shall lie in the range 0 to 7. |
5+
| test.c:20:9:20:10 | 64 | The shift right hand operand shall lie in the range 0 to 63. |
6+
| test.c:23:10:23:11 | 10 | The shift right hand operand shall lie in the range 0 to 7. |
7+
| test.c:24:10:24:11 | 64 | The shift right hand operand shall lie in the range 0 to 7. |
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
rules/RULE-12-2/RightHandOperandOfAShiftRange.ql

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

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#include <stdint.h>
2+
3+
void f1() {
4+
uint8_t ui8;
5+
int b = 4;
6+
7+
ui8 << 7; // COMPLIANT
8+
ui8 >> 8; // NON_COMPLIANT
9+
ui8 << 3 + 3; // COMPLIANT
10+
ui8 >> 4 + b; // NON_COMPLIANT
11+
ui8 << b + b; // NON_COMPLIANT
12+
(uint16_t) ui8 << 9; // COMPLIANT
13+
14+
// 0u essential type is essentially unsigned char
15+
0u << 8; // NON_COMPLIANT
16+
(uint16_t)0u << 8; // COMPLIANT
17+
18+
unsigned long ul;
19+
ul << 10; // COMPLIANT
20+
ul << 64; // NON_COMPLIANT
21+
22+
// 1UL essential type is essentially unsigned long
23+
1UL << 10; // COMPLIANT(FALSE_POSITIVE)
24+
1UL << 64; // NON_COMPLIANT
25+
}

0 commit comments

Comments
 (0)