Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions change_notes/2026-03-16-share-divisor-equal-to-zero-query.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
- `A5-6-1` - `DivisorEqualToZero.ql`:
- 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.
12 changes: 6 additions & 6 deletions cpp/autosar/src/rules/A5-6-1/DivisorEqualToZero.ql
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@

import cpp
import codingstandards.cpp.autosar
import codingstandards.cpp.rules.divisorequaltozeroshared.DivisorEqualToZeroShared

from BinaryArithmeticOperation bao
where
not isExcluded(bao, ExpressionsPackage::divisorEqualToZeroQuery()) and
(bao instanceof DivExpr or bao instanceof RemExpr) and
bao.getRightOperand().getValue().toFloat() = 0 // `toFloat()` holds for both integer and float literals.
select bao, "Divisor is zero."
module DivisorEqualToZeroConfig implements DivisorEqualToZeroSharedConfigSig {
Query getQuery() { result = ExpressionsPackage::divisorEqualToZeroQuery() }
}

import DivisorEqualToZeroShared<DivisorEqualToZeroConfig>
1 change: 0 additions & 1 deletion cpp/autosar/test/rules/A5-6-1/DivisorEqualToZero.qlref

This file was deleted.

1 change: 1 addition & 0 deletions cpp/autosar/test/rules/A5-6-1/DivisorEqualToZero.testref
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
cpp/common/test/rules/divisorequaltozeroshared/DivisorEqualToZeroShared.ql
19 changes: 18 additions & 1 deletion cpp/common/src/codingstandards/cpp/exclusions/cpp/Undefined.qll
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ newtype UndefinedQuery =
TCriticalUnspecifiedBehaviorQuery() or
TUndefinedBehaviorAuditQuery() or
TCriticalUnspecifiedBehaviorAuditQuery() or
TPossibleDataRaceBetweenThreadsQuery()
TPossibleDataRaceBetweenThreadsQuery() or
TDivisionByZeroUndefinedBehaviorQuery()

predicate isUndefinedQueryMetadata(Query query, string queryId, string ruleId, string category) {
query =
Expand Down Expand Up @@ -55,6 +56,15 @@ predicate isUndefinedQueryMetadata(Query query, string queryId, string ruleId, s
"cpp/misra/possible-data-race-between-threads" and
ruleId = "RULE-4-1-3" and
category = "required"
or
query =
// `Query` instance for the `divisionByZeroUndefinedBehavior` query
UndefinedPackage::divisionByZeroUndefinedBehaviorQuery() and
queryId =
// `@id` for the `divisionByZeroUndefinedBehavior` query
"cpp/misra/division-by-zero-undefined-behavior" and
ruleId = "RULE-4-1-3" and
category = "required"
}

module UndefinedPackage {
Expand Down Expand Up @@ -92,4 +102,11 @@ module UndefinedPackage {
// `Query` type for `possibleDataRaceBetweenThreads` query
TQueryCPP(TUndefinedPackageQuery(TPossibleDataRaceBetweenThreadsQuery()))
}

Query divisionByZeroUndefinedBehaviorQuery() {
//autogenerate `Query` type
result =
// `Query` type for `divisionByZeroUndefinedBehavior` query
TQueryCPP(TUndefinedPackageQuery(TDivisionByZeroUndefinedBehaviorQuery()))
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/**
* Provides a configurable module DivisorEqualToZeroShared with a `problems` predicate
* for the following issue:
* The result is undefined if the right hand operand of the integer division or the
* remainder operator is zero.
*/

import cpp
import codingstandards.cpp.Customizations
import codingstandards.cpp.Exclusions

signature module DivisorEqualToZeroSharedConfigSig {
Query getQuery();
}

module DivisorEqualToZeroShared<DivisorEqualToZeroSharedConfigSig Config> {
query predicate problems(BinaryArithmeticOperation bao, string message) {
not isExcluded(bao, Config::getQuery()) and
(bao instanceof DivExpr or bao instanceof RemExpr) and
bao.getRightOperand().getValue().toFloat() = 0 and // `toFloat()` holds for both integer and float literals.
message = "Divisor is zero."
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@
| test.cpp:28:11:28:18 | ... / ... | Divisor is zero. |
| test.cpp:29:11:29:18 | ... % ... | Divisor is zero. |
| test.cpp:30:11:30:18 | ... / ... | Divisor is zero. |
| test.cpp:31:11:31:18 | ... % ... | Divisor is zero. |
| test.cpp:31:11:31:18 | ... % ... | Divisor is zero. |
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// GENERATED FILE - DO NOT MODIFY
import codingstandards.cpp.rules.divisorequaltozeroshared.DivisorEqualToZeroShared

module TestFileConfig implements DivisorEqualToZeroSharedConfigSig {
Query getQuery() { result instanceof TestQuery }
}

import DivisorEqualToZeroShared<TestFileConfig>
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,4 @@ void test_macro() {
int f = 1 % ONE; // COMPLIANT
int g = 1 / ID(1); // COMPLIANT
int h = 1 % ID(1); // COMPLIANT
}
}
23 changes: 23 additions & 0 deletions cpp/misra/src/rules/RULE-4-1-3/DivisionByZeroUndefinedBehavior.ql
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/**
* @id cpp/misra/division-by-zero-undefined-behavior
* @name RULE-4-1-3: Division or modulo by zero leads to undefined behavior
* @description Division or remainder by zero results in undefined behavior.
* @kind problem
* @precision high
* @problem.severity error
* @tags external/misra/id/rule-4-1-3
* correctness
* scope/system
* external/misra/enforcement/undecidable
* external/misra/obligation/required
*/

import cpp
import codingstandards.cpp.misra
import codingstandards.cpp.rules.divisorequaltozeroshared.DivisorEqualToZeroShared

module DivisionByZeroUndefinedBehaviorConfig implements DivisorEqualToZeroSharedConfigSig {
Query getQuery() { result = UndefinedPackage::divisionByZeroUndefinedBehaviorQuery() }
}

import DivisorEqualToZeroShared<DivisionByZeroUndefinedBehaviorConfig>
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
cpp/common/test/rules/divisorequaltozeroshared/DivisorEqualToZeroShared.ql
1 change: 1 addition & 0 deletions rule_packages/cpp/Expressions.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
"name": "The right operand of the integer division or remainder operators shall not be equal to zero",
"precision": "high",
"severity": "error",
"shared_implementation_short_name": "DivisorEqualToZeroShared",
"short_name": "DivisorEqualToZero",
"tags": [
"correctness"
Expand Down
13 changes: 13 additions & 0 deletions rule_packages/cpp/Undefined.json
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,19 @@
"concurrency",
"scope/system"
]
},
{
"description": "Division or remainder by zero results in undefined behavior.",
"kind": "problem",
"name": "Division or modulo by zero leads to undefined behavior",
"precision": "high",
"severity": "error",
"shared_implementation_short_name": "DivisorEqualToZeroShared",
"short_name": "DivisionByZeroUndefinedBehavior",
"tags": [
"correctness",
"scope/system"
]
}
],
"title": "There shall be no occurrence of undefined or critical unspecified behaviour"
Expand Down
Loading