Skip to content

Commit 2756406

Browse files
Merge pull request #1087 from github/michaelrfairhurst/package-undefined-behavior-divide-or-modulo-by-zero
Import A5-6-1 division/mod by zero
2 parents 7e4819f + 78a2db9 commit 2756406

File tree

13 files changed

+97
-9
lines changed

13 files changed

+97
-9
lines changed
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
- `A5-6-1` - `DivisorEqualToZero.ql`:
2+
- Refactored query logic into a shared library (`DivisorEqualToZeroShared.qll`) to enable reuse by MISRA C++ `RULE-4-1-3`. The query logic is unchanged and no visible changes to results or performance are expected.

cpp/autosar/src/rules/A5-6-1/DivisorEqualToZero.ql

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,10 @@
1515

1616
import cpp
1717
import codingstandards.cpp.autosar
18+
import codingstandards.cpp.rules.divisorequaltozeroshared.DivisorEqualToZeroShared
1819

19-
from BinaryArithmeticOperation bao
20-
where
21-
not isExcluded(bao, ExpressionsPackage::divisorEqualToZeroQuery()) and
22-
(bao instanceof DivExpr or bao instanceof RemExpr) and
23-
bao.getRightOperand().getValue().toFloat() = 0 // `toFloat()` holds for both integer and float literals.
24-
select bao, "Divisor is zero."
20+
module DivisorEqualToZeroConfig implements DivisorEqualToZeroSharedConfigSig {
21+
Query getQuery() { result = ExpressionsPackage::divisorEqualToZeroQuery() }
22+
}
23+
24+
import DivisorEqualToZeroShared<DivisorEqualToZeroConfig>

cpp/autosar/test/rules/A5-6-1/DivisorEqualToZero.qlref

Lines changed: 0 additions & 1 deletion
This file was deleted.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
cpp/common/test/rules/divisorequaltozeroshared/DivisorEqualToZeroShared.ql

cpp/common/src/codingstandards/cpp/exclusions/cpp/Undefined.qll

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ newtype UndefinedQuery =
99
TUndefinedBehaviorAuditQuery() or
1010
TCriticalUnspecifiedBehaviorAuditQuery() or
1111
TPossibleDataRaceBetweenThreadsQuery() or
12+
TDivisionByZeroUndefinedBehaviorQuery() or
1213
TDeallocationTypeMismatchQuery() or
1314
TStringLiteralPossiblyModifiedAuditQuery()
1415

@@ -58,6 +59,15 @@ predicate isUndefinedQueryMetadata(Query query, string queryId, string ruleId, s
5859
ruleId = "RULE-4-1-3" and
5960
category = "required"
6061
or
62+
query =
63+
// `Query` instance for the `divisionByZeroUndefinedBehavior` query
64+
UndefinedPackage::divisionByZeroUndefinedBehaviorQuery() and
65+
queryId =
66+
// `@id` for the `divisionByZeroUndefinedBehavior` query
67+
"cpp/misra/division-by-zero-undefined-behavior" and
68+
ruleId = "RULE-4-1-3" and
69+
category = "required"
70+
or
6171
query =
6272
// `Query` instance for the `deallocationTypeMismatch` query
6373
UndefinedPackage::deallocationTypeMismatchQuery() and
@@ -113,6 +123,13 @@ module UndefinedPackage {
113123
TQueryCPP(TUndefinedPackageQuery(TPossibleDataRaceBetweenThreadsQuery()))
114124
}
115125

126+
Query divisionByZeroUndefinedBehaviorQuery() {
127+
//autogenerate `Query` type
128+
result =
129+
// `Query` type for `divisionByZeroUndefinedBehavior` query
130+
TQueryCPP(TUndefinedPackageQuery(TDivisionByZeroUndefinedBehaviorQuery()))
131+
}
132+
116133
Query deallocationTypeMismatchQuery() {
117134
//autogenerate `Query` type
118135
result =
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/**
2+
* Provides a configurable module DivisorEqualToZeroShared with a `problems` predicate
3+
* for the following issue:
4+
* The result is undefined if the right hand operand of the integer division or the
5+
* remainder operator is zero.
6+
*/
7+
8+
import cpp
9+
import codingstandards.cpp.Customizations
10+
import codingstandards.cpp.Exclusions
11+
12+
signature module DivisorEqualToZeroSharedConfigSig {
13+
Query getQuery();
14+
}
15+
16+
module DivisorEqualToZeroShared<DivisorEqualToZeroSharedConfigSig Config> {
17+
query predicate problems(BinaryArithmeticOperation bao, string message) {
18+
not isExcluded(bao, Config::getQuery()) and
19+
(bao instanceof DivExpr or bao instanceof RemExpr) and
20+
bao.getRightOperand().getValue().toFloat() = 0 and // `toFloat()` holds for both integer and float literals.
21+
message = "Divisor is zero."
22+
}
23+
}

cpp/autosar/test/rules/A5-6-1/DivisorEqualToZero.expected renamed to cpp/common/test/rules/divisorequaltozeroshared/DivisorEqualToZeroShared.expected

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,4 @@
1010
| test.cpp:28:11:28:18 | ... / ... | Divisor is zero. |
1111
| test.cpp:29:11:29:18 | ... % ... | Divisor is zero. |
1212
| test.cpp:30:11:30:18 | ... / ... | Divisor is zero. |
13-
| test.cpp:31:11:31:18 | ... % ... | Divisor is zero. |
13+
| test.cpp:31:11:31:18 | ... % ... | Divisor is zero. |
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// GENERATED FILE - DO NOT MODIFY
2+
import codingstandards.cpp.rules.divisorequaltozeroshared.DivisorEqualToZeroShared
3+
4+
module TestFileConfig implements DivisorEqualToZeroSharedConfigSig {
5+
Query getQuery() { result instanceof TestQuery }
6+
}
7+
8+
import DivisorEqualToZeroShared<TestFileConfig>

cpp/autosar/test/rules/A5-6-1/test.cpp renamed to cpp/common/test/rules/divisorequaltozeroshared/test.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,4 +35,4 @@ void test_macro() {
3535
int f = 1 % ONE; // COMPLIANT
3636
int g = 1 / ID(1); // COMPLIANT
3737
int h = 1 % ID(1); // COMPLIANT
38-
}
38+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/**
2+
* @id cpp/misra/division-by-zero-undefined-behavior
3+
* @name RULE-4-1-3: Division or modulo by zero leads to undefined behavior
4+
* @description Division or remainder by zero results in undefined behavior.
5+
* @kind problem
6+
* @precision high
7+
* @problem.severity error
8+
* @tags external/misra/id/rule-4-1-3
9+
* correctness
10+
* scope/system
11+
* external/misra/enforcement/undecidable
12+
* external/misra/obligation/required
13+
*/
14+
15+
import cpp
16+
import codingstandards.cpp.misra
17+
import codingstandards.cpp.rules.divisorequaltozeroshared.DivisorEqualToZeroShared
18+
19+
module DivisionByZeroUndefinedBehaviorConfig implements DivisorEqualToZeroSharedConfigSig {
20+
Query getQuery() { result = UndefinedPackage::divisionByZeroUndefinedBehaviorQuery() }
21+
}
22+
23+
import DivisorEqualToZeroShared<DivisionByZeroUndefinedBehaviorConfig>

0 commit comments

Comments
 (0)