Skip to content

Commit 592bc18

Browse files
committed
C++: Reduce FPs by excluding all commas in loop heads
This leads to a 50% reduction of alerts in MRVA 1000.
1 parent 823b010 commit 592bc18

File tree

2 files changed

+17
-12
lines changed

2 files changed

+17
-12
lines changed

cpp/ql/src/Best Practices/Likely Errors/CommaBeforeMisleadingIndentation.ql

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,12 @@ Expr normalizeExpr(Expr e) {
2020
else result = e
2121
}
2222

23+
predicate isInLoopHead(CommaExpr ce) {
24+
ce.getParent*() = [any(Loop l).getCondition(), any(ForStmt f).getUpdate()]
25+
or
26+
ce.getEnclosingStmt() = any(ForStmt f).getInitialization()
27+
}
28+
2329
from CommaExpr ce, Expr left, Expr right, Location leftLoc, Location rightLoc
2430
where
2531
ce.fromSource() and
@@ -28,6 +34,7 @@ where
2834
right = normalizeExpr(ce.getRightOperand()) and
2935
leftLoc = left.getLocation() and
3036
rightLoc = right.getLocation() and
37+
not isInLoopHead(ce) and // HACK to reduce FPs in loop heads; assumption: unlikely to be misread due to '(', ')' delimiters
3138
leftLoc.getEndLine() < rightLoc.getStartLine() and
3239
leftLoc.getStartColumn() > rightLoc.getStartColumn()
33-
select right, "The indentation level after the comma can be misleading (for some tab sizes)."
40+
select right, "The indentation after the comma may be misleading (for some tab sizes)."

cpp/ql/test/query-tests/Best Practices/Likely Errors/CommaBeforeMisleadingIndentation/test.cpp

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,15 @@ int test(int i, int j, int (*foo)(int), int (*bar)(int, int))
8686
i = j = i + j;
8787
}
8888

89+
for (i = 0, // GOOD? Currently ignoring loop heads.
90+
j = 1;
91+
i + j < 10;
92+
i++, j++);
93+
94+
for (i = 0,
95+
j = 1; i < 10; i += 2, // GOOD? Currently ignoring loop heads.
96+
j++) {}
97+
8998
// Mixed tabs and spaces (ugly case):
9099

91100
for (i = 0, // GOOD if tab >= 4 spaces else BAD -- can't exclude w/o source code text :/
@@ -98,17 +107,6 @@ int test(int i, int j, int (*foo)(int), int (*bar)(int, int))
98107
(void)i, // GOOD if tab >= 4 spaces else BAD -- can't exclude w/o source code text :/
99108
(void)j;
100109

101-
// One char difference (common but borderline):
102-
103-
for (i = 0, // GOOD? [FALSE POSITIVE] -- can't exclude w/o source code text :/
104-
j = 1;
105-
i + j < 10;
106-
i++, j++);
107-
108-
for (i = 0,
109-
j = 1; i < 10; i += 2, // GOOD? [FALSE POSITIVE] -- can't exclude w/o source code text :/
110-
j++) {}
111-
112110
// LHS ends on same line RHS begins on:
113111

114112
int k = (foo(

0 commit comments

Comments
 (0)