Skip to content

Commit 8931f91

Browse files
committed
Reuse logic from INT34-C to detect guarded shifts
1 parent 8869b9e commit 8931f91

File tree

3 files changed

+33
-1
lines changed

3 files changed

+33
-1
lines changed

cpp/autosar/test/rules/A4-7-1/IntegerExpressionLeadToDataLoss.expected

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,6 @@
1010
| test.cpp:22:12:22:16 | ... + ... | Binary expression ...+... may overflow. |
1111
| test.cpp:50:7:50:14 | ... + ... | Binary expression ...+... may overflow. |
1212
| test.cpp:62:8:62:10 | ... ++ | Binary expression ...++... may overflow. |
13+
| test.cpp:91:10:91:17 | ... << ... | Binary expression ...<<... may overflow. |
14+
| test.cpp:95:10:95:17 | ... << ... | Binary expression ...<<... may overflow. |
15+
| test.cpp:98:8:98:15 | ... << ... | Binary expression ...<<... may overflow. |

cpp/autosar/test/rules/A4-7-1/test.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,4 +72,29 @@ void test_pointer() {
7272
int *p = nullptr;
7373
p++; // COMPLIANT - not covered by this rule
7474
p--; // COMPLIANT - not covered by this rule
75+
}
76+
77+
extern unsigned int popcount(unsigned int);
78+
#define PRECISION(x) popcount(x)
79+
void test_guarded_shifts(unsigned int p1, int p2) {
80+
unsigned int l1;
81+
82+
if (p2 < popcount(p1) && p2 > 0) {
83+
l1 = p1 << p2; // COMPLIANT
84+
}
85+
86+
if (p2 < PRECISION(p1) && p2 > 0) {
87+
l1 = p1 << p2; // COMPLIANT
88+
}
89+
90+
if (p2 < popcount(p1)) {
91+
l1 = p1 << p2; // NON_COMPLIANT - p2 could be negative
92+
}
93+
94+
if (p2 > 0) {
95+
l1 = p1 << p2; // NON_COMPLIANT - p2 could have a higher precision
96+
}
97+
98+
l1 = p1 << p2; // NON_COMPLIANT - p2 may have a higher precision or could be
99+
// negative
75100
}

cpp/common/src/codingstandards/cpp/Overflow.qll

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ import SimpleRangeAnalysisCustomizations
88
import semmle.code.cpp.controlflow.Guards
99
import codingstandards.cpp.dataflow.TaintTracking
1010
import semmle.code.cpp.valuenumbering.GlobalValueNumbering
11+
import codingstandards.cpp.Expr
12+
import codingstandards.cpp.UndefinedBehavior
1113

1214
/**
1315
* An integer operation that may overflow, underflow or wrap.
@@ -40,7 +42,9 @@ class InterestingOverflowingOperation extends Operation {
4042
// Not within a macro
4143
not this.isAffectedByMacro() and
4244
// Ignore pointer arithmetic
43-
not this instanceof PointerArithmeticOperation
45+
not this instanceof PointerArithmeticOperation and
46+
// In case of the shift operation, it must cause undefined behavior
47+
(this instanceof BitShiftExpr implies this instanceof ShiftByNegativeOrGreaterPrecisionOperand)
4448
}
4549

4650
/**

0 commit comments

Comments
 (0)