Skip to content

Commit ac3feff

Browse files
committed
M6-5-5: Improve detection of modification by reference
- No longer consider the taking of a const reference as a modification. - Consider taking a non-const reference of a potential loop counter as modifying that loop counter. - Update tests to reflect changes.
1 parent 9f408a0 commit ac3feff

File tree

4 files changed

+39
-2
lines changed

4 files changed

+39
-2
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
* `M6-5-5`
2+
- Reduce false positives by no longer considering the taking of a const reference as a modification.
3+
- Improve detection of non-local modification of loop iteration variables to reduce false positives.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
| test.cpp:24:8:24:15 | testFlag | Loop control variable testFlag is modified in the loop update expression. |
2+
| test.cpp:47:12:47:12 | y | Loop control variable y is modified in the loop update expression. |

cpp/autosar/test/rules/M6-5-5/test.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,27 @@ void test_loop_control_variable_modified_in_expression() {
2424
testFlag = updateFlagWithIncrement(++x)) { // NON_COMPLIANT
2525
}
2626
}
27+
28+
#include <vector>
29+
30+
void test_const_refs(std::vector<int> v) {
31+
std::vector<int>::iterator first = v.begin();
32+
std::vector<int>::iterator last = v.end();
33+
// call to operator!= passes a const reference to first
34+
for (; first != last; first++) { // COMPLIANT
35+
}
36+
}
37+
38+
void update(std::vector<int>::iterator &f, const int &x, int &y) {}
39+
40+
void test_const_refs_update(std::vector<int> v) {
41+
std::vector<int>::iterator last = v.end();
42+
int x = 0;
43+
int y = 0;
44+
// call to operator!= passes a const reference to first
45+
for (std::vector<int>::iterator first = v.begin(); first != last; update(
46+
first, x, // COMPLIANT - first is a loop counter, so can be modified
47+
y)) { // NON_COMPLIANT - y is modified and is not a loop counter
48+
first + 1;
49+
}
50+
}

cpp/common/src/codingstandards/cpp/Loops.qll

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,15 @@ Variable getALoopCounter(ForStmt fs) {
106106
)
107107
or
108108
updateOp = result.getAnAssignedValue()
109+
or
110+
// updateOp is an access whose address is taken in a non-const way
111+
exists(FunctionCall fc, VariableAccess va |
112+
fc = updateOp and
113+
fc instanceof FunctionCall and
114+
fc.getAnArgument() = va and
115+
va = result.getAnAccess() and
116+
va.isAddressOfAccessNonConst()
117+
)
109118
) and
110119
result instanceof Variable and
111120
// checked or used in the condition
@@ -260,7 +269,7 @@ predicate isLoopControlVarModifiedInLoopCondition(
260269
loopControlVariableAccess = forLoop.getCondition().getAChild+() and
261270
(
262271
loopControlVariableAccess.isModified() or
263-
loopControlVariableAccess.isAddressOfAccess()
272+
loopControlVariableAccess.isAddressOfAccessNonConst()
264273
)
265274
}
266275

@@ -277,7 +286,7 @@ predicate isLoopControlVarModifiedInLoopExpr(
277286
loopControlVariableAccess = forLoop.getUpdate().getAChild() and
278287
(
279288
loopControlVariableAccess.isModified() or
280-
loopControlVariableAccess.isAddressOfAccess()
289+
loopControlVariableAccess.isAddressOfAccessNonConst()
281290
)
282291
}
283292

0 commit comments

Comments
 (0)