Skip to content

Commit e9c0c18

Browse files
committed
IntegerOverflow: Do not exclude casted expressions
Constant binary expressions which are immediately casted to a signed type should not be excluded from this rule, because the "wrap" will still occur.
1 parent 9580891 commit e9c0c18

File tree

6 files changed

+20
-4
lines changed

6 files changed

+20
-4
lines changed

c/common/test/rules/constantunsignedintegerexpressionswraparound/ConstantUnsignedIntegerExpressionsWrapAround.expected

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,4 @@
1414
| test.c:47:7:47:18 | ... - ... | Use of a constant, unsigned, integer expression that over- or under-flows. |
1515
| test.c:48:7:48:17 | ... + ... | Use of a constant, unsigned, integer expression that over- or under-flows. |
1616
| test.c:48:7:48:17 | ... + ... | Use of a constant, unsigned, integer expression that over- or under-flows. |
17+
| test.c:53:20:53:31 | ... + ... | Use of a constant, unsigned, integer expression that over- or under-flows. |

c/common/test/rules/constantunsignedintegerexpressionswraparound/test.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66

77
void test_unsigned_int() {
88
unsigned int a;
9-
a = 1 + 1; // COMPLIANT
10-
a = 0 - 1; // COMPLIANT
9+
a = 1 + 1; // COMPLIANT - signed integer
10+
a = 0 - 1; // COMPLIANT - signed integer
1111
a = UINT_MIN - 1; // NON_COMPLIANT
1212
a = UINT_MAX + 1; // NON_COMPLIANT
1313

@@ -46,4 +46,10 @@ void test_long_long() {
4646
a = OVERFLOW(0); // COMPLIANT
4747
a = UNDERFLOW(1); // NON_COMPLIANT
4848
a = OVERFLOW(1); // NON_COMPLIANT
49+
}
50+
51+
void test_conversion() {
52+
signed int a =
53+
(signed int)(UINT_MAX + 1); // NON_COMPLIANT - still an unsigned integer
54+
// constant expression
4955
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
* `M5-19-1`:
2+
- Reduce false negatives by fixing a bug where a constant expression was immediately casted to a signed type.

cpp/common/src/codingstandards/cpp/rules/constantunsignedintegerexpressionswraparound/ConstantUnsignedIntegerExpressionsWrapAround.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ Query getQuery() { result instanceof ConstantUnsignedIntegerExpressionsWrapAroun
1515
query predicate problems(BinaryArithmeticOperation bao, string message) {
1616
not isExcluded(bao, getQuery()) and
1717
bao.isConstant() and
18-
bao.getFullyConverted().getUnderlyingType().(IntegralType).isUnsigned() and
18+
bao.getUnderlyingType().(IntegralType).isUnsigned() and
1919
convertedExprMightOverflow(bao) and
2020
message = "Use of a constant, unsigned, integer expression that over- or under-flows."
2121
}

cpp/common/test/rules/constantunsignedintegerexpressionswraparound/ConstantUnsignedIntegerExpressionsWrapAround.expected

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,4 @@
1414
| test.cpp:59:7:59:17 | ... + ... | Use of a constant, unsigned, integer expression that over- or under-flows. |
1515
| test.cpp:63:7:63:45 | ... - ... | Use of a constant, unsigned, integer expression that over- or under-flows. |
1616
| test.cpp:64:7:64:45 | ... + ... | Use of a constant, unsigned, integer expression that over- or under-flows. |
17+
| test.cpp:69:20:69:31 | ... + ... | Use of a constant, unsigned, integer expression that over- or under-flows. |

cpp/common/test/rules/constantunsignedintegerexpressionswraparound/test.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ template <typename T> constexpr T constexpr_max() {
99
return std::numeric_limits<T>::max();
1010
}
1111

12-
void test_signed_int() {
12+
void test_unsigned_int() {
1313
unsigned int a;
1414
a = 1 + 1; // COMPLIANT
1515
a = 0 - 1; // COMPLIANT
@@ -62,4 +62,10 @@ void test_long_long() {
6262
a = constexpr_max<unsigned long long>() - 1; // COMPLIANT
6363
a = constexpr_min<unsigned long long>() - 1; // NON_COMPLIANT
6464
a = constexpr_max<unsigned long long>() + 1; // NON_COMPLIANT
65+
}
66+
67+
void test_conversion() {
68+
signed int a =
69+
(signed int)(UINT_MAX + 1); // NON_COMPLIANT - still an unsigned integer
70+
// constant expression
6571
}

0 commit comments

Comments
 (0)