diff --git a/change_notes/2024-10-22-fix-fp-m6-5-3.md b/change_notes/2024-10-22-fix-fp-m6-5-3.md new file mode 100644 index 0000000000..0d8ca573d9 --- /dev/null +++ b/change_notes/2024-10-22-fix-fp-m6-5-3.md @@ -0,0 +1,2 @@ +- `M6-5-3` - `Loops.qll`: + - Fixes #755. Specifies that the access to the loop counter must be via non-const address. diff --git a/cpp/autosar/test/rules/A18-1-1/test.cpp b/cpp/autosar/test/rules/A18-1-1/test.cpp index 90596780d9..0e9bffa3d7 100644 --- a/cpp/autosar/test/rules/A18-1-1/test.cpp +++ b/cpp/autosar/test/rules/A18-1-1/test.cpp @@ -11,6 +11,6 @@ int test_c_arrays() { int x[100]; // NON_COMPLIANT constexpr int a[]{0, 1, 2}; // NON_COMPLIANT - __func__; // COMPLAINT + __func__; // COMPLIANT return 0; -} \ No newline at end of file +} diff --git a/cpp/autosar/test/rules/M6-5-3/LoopCounterModifiedWithinStatement.expected b/cpp/autosar/test/rules/M6-5-3/LoopCounterModifiedWithinStatement.expected index a6988586f0..4643298e3a 100644 --- a/cpp/autosar/test/rules/M6-5-3/LoopCounterModifiedWithinStatement.expected +++ b/cpp/autosar/test/rules/M6-5-3/LoopCounterModifiedWithinStatement.expected @@ -2,3 +2,4 @@ | test.cpp:25:35:25:35 | x | Loop counters should not be modified within a statement in a for loop. | | test.cpp:36:5:36:5 | x | Loop counters should not be modified within a statement in a for loop. | | test.cpp:43:9:43:9 | i | Loop counters should not be modified within a statement in a for loop. | +| test.cpp:93:15:93:15 | i | Loop counters should not be modified within a statement in a for loop. | diff --git a/cpp/autosar/test/rules/M6-5-3/test.cpp b/cpp/autosar/test/rules/M6-5-3/test.cpp index a534e6ba8e..a41ba8a22d 100644 --- a/cpp/autosar/test/rules/M6-5-3/test.cpp +++ b/cpp/autosar/test/rules/M6-5-3/test.cpp @@ -43,3 +43,54 @@ void test_loop_counter_mod_in_side_effect() { inc(i); // NON_COMPLIANT - modifies `i` } } + +void test_loop_counter_reference_mod_in_condition() { + auto loop = [](int &i) { + for (; (i++ < 10); i++) { // NON_COMPLIANT + } + }; + int i = 0; + loop(i); +} + +void test_loop_counter_reference_mod() { + auto loop = [](int &i) { + for (; i < 10; i++) { // COMPLIANT + } + }; + int i = 0; + loop(i); +} + +void test_loop_const_reference() { + auto loop = []([[maybe_unused]] int const &i) { + for (int i = 0; i < 10; i++) { // COMPLIANT + } + }; + int i = 0; + loop(i); +} + +void test_loop_counter_reference_mod_in_statement() { + auto loop = [](int &i) { + for (; (i < 10); i++) { + i++; // NON_COMPLIANT + } + }; + int i = 0; + loop(i); +} + +int const_reference(int const &i) { return i; } + +int reference(int &i) { return i; } + +int copy(int i) { return i; } + +void test_pass_argument_by() { + for (int i = 0; i < 10; i++) { + const_reference(i); // COMPLIANT + reference(i); // NON_COMPLIANT + copy(i); // COMPLIANT + } +} diff --git a/cpp/common/src/codingstandards/cpp/Loops.qll b/cpp/common/src/codingstandards/cpp/Loops.qll index bfd68c49a0..aa3dc64ea5 100644 --- a/cpp/common/src/codingstandards/cpp/Loops.qll +++ b/cpp/common/src/codingstandards/cpp/Loops.qll @@ -204,7 +204,7 @@ predicate isLoopCounterModifiedInCondition(ForStmt forLoop, VariableAccess loopC loopCounterAccess = getAnIterationVariable(forLoop).getAnAccess() and ( loopCounterAccess.isModified() or - loopCounterAccess.isAddressOfAccess() + loopCounterAccess.isAddressOfAccessNonConst() ) } @@ -219,7 +219,7 @@ predicate isLoopCounterModifiedInStatement( loopCounterAccess = loopCounter.getAnAccess() and ( loopCounterAccess.isModified() or - loopCounterAccess.isAddressOfAccess() + loopCounterAccess.isAddressOfAccessNonConst() ) and forLoop.getStmt().getChildStmt*() = loopCounterAccess.getEnclosingStmt() }