diff --git a/c/common/test/rules/unsignedoperationwithconstantoperandswraps/test.c b/c/common/test/rules/unsignedoperationwithconstantoperandswraps/test.c index 214b18a44f..05afe496a6 100644 --- a/c/common/test/rules/unsignedoperationwithconstantoperandswraps/test.c +++ b/c/common/test/rules/unsignedoperationwithconstantoperandswraps/test.c @@ -80,4 +80,11 @@ void test_sub_postcheck(unsigned int i1, unsigned int i2) { if (i1 > i2) { // handle error } +} + +void test_mod_rem(unsigned int i1, unsigned int i2) { + i1 / i2; // COMPLIANT - exception 2 + i1 /= i2; // COMPLIANT - exception 2 + i1 % i2; // COMPLIANT - exception 2 + i1 %= i2; // COMPLIANT - exception 2 } \ No newline at end of file diff --git a/change_notes/2026-06-18-fix-fp-misra-c++-8-20-1.md b/change_notes/2026-06-18-fix-fp-misra-c++-8-20-1.md new file mode 100644 index 0000000000..55bfb0f213 --- /dev/null +++ b/change_notes/2026-06-18-fix-fp-misra-c++-8-20-1.md @@ -0,0 +1,4 @@ +- `INT30-C` - `UnsignedIntegerOperationsWrapAround.ql`: + - Fixed false positives for `/=` and `%=` assignments. +- `RULE-8-20-1` - `UnsignedOperationWithConstantOperandsWraps.ql`: + - Fixed false positives for `/=` and `%=` assignments. diff --git a/cpp/common/src/codingstandards/cpp/rules/unsignedoperationwithconstantoperandswraps/UnsignedOperationWithConstantOperandsWraps.qll b/cpp/common/src/codingstandards/cpp/rules/unsignedoperationwithconstantoperandswraps/UnsignedOperationWithConstantOperandsWraps.qll index bc0c6d8fc1..06f4cb0868 100644 --- a/cpp/common/src/codingstandards/cpp/rules/unsignedoperationwithconstantoperandswraps/UnsignedOperationWithConstantOperandsWraps.qll +++ b/cpp/common/src/codingstandards/cpp/rules/unsignedoperationwithconstantoperandswraps/UnsignedOperationWithConstantOperandsWraps.qll @@ -26,8 +26,7 @@ query predicate problems(InterestingOverflowingOperation op, string message) { // Permitted by exception 3 not op instanceof LShiftExpr and // Permitted by exception 2 - zero case is handled in separate query - not op instanceof DivExpr and - not op instanceof RemExpr and + not op instanceof DivOrRemOperation and message = "Operation " + op.getOperator() + " of type " + op.getType().getUnderlyingType() + " may wrap." } diff --git a/cpp/common/test/rules/unsignedoperationwithconstantoperandswraps/test.cpp b/cpp/common/test/rules/unsignedoperationwithconstantoperandswraps/test.cpp index 8f76fbeeeb..31a561cdbf 100644 --- a/cpp/common/test/rules/unsignedoperationwithconstantoperandswraps/test.cpp +++ b/cpp/common/test/rules/unsignedoperationwithconstantoperandswraps/test.cpp @@ -80,4 +80,11 @@ void test_sub_postcheck(unsigned int i1, unsigned int i2) { if (i1 > i2) { // handle error } +} + +void test_mod_rem(unsigned int i1, unsigned int i2) { + i1 / i2; // COMPLIANT - exception 2 + i1 /= i2; // COMPLIANT - exception 2 + i1 % i2; // COMPLIANT - exception 2 + i1 %= i2; // COMPLIANT - exception 2 } \ No newline at end of file