diff --git a/cpp/ql/src/Best Practices/Likely Errors/CommaBeforeMisleadingIndentation.ql b/cpp/ql/src/Best Practices/Likely Errors/CommaBeforeMisleadingIndentation.ql index a786f4aec33..f2cd6bed55f 100644 --- a/cpp/ql/src/Best Practices/Likely Errors/CommaBeforeMisleadingIndentation.ql +++ b/cpp/ql/src/Best Practices/Likely Errors/CommaBeforeMisleadingIndentation.ql @@ -20,6 +20,12 @@ Expr normalizeExpr(Expr e) { else result = e } +predicate isInLoopHead(CommaExpr ce) { + ce.getParent*() = [any(Loop l).getCondition(), any(ForStmt f).getUpdate()] + or + ce.getEnclosingStmt() = any(ForStmt f).getInitialization() +} + from CommaExpr ce, Expr left, Expr right, Location leftLoc, Location rightLoc where ce.fromSource() and @@ -28,6 +34,7 @@ where right = normalizeExpr(ce.getRightOperand()) and leftLoc = left.getLocation() and rightLoc = right.getLocation() and + not isInLoopHead(ce) and // HACK to reduce FPs in loop heads; assumption: unlikely to be misread due to '(', ')' delimiters leftLoc.getEndLine() < rightLoc.getStartLine() and leftLoc.getStartColumn() > rightLoc.getStartColumn() -select right, "The indentation level after the comma can be misleading (for some tab sizes)." +select right, "The indentation after the comma may be misleading (for some tab sizes)." diff --git a/cpp/ql/test/query-tests/Best Practices/Likely Errors/CommaBeforeMisleadingIndentation/test.cpp b/cpp/ql/test/query-tests/Best Practices/Likely Errors/CommaBeforeMisleadingIndentation/test.cpp index cdbb46bed95..8237bb7253e 100644 --- a/cpp/ql/test/query-tests/Best Practices/Likely Errors/CommaBeforeMisleadingIndentation/test.cpp +++ b/cpp/ql/test/query-tests/Best Practices/Likely Errors/CommaBeforeMisleadingIndentation/test.cpp @@ -86,6 +86,15 @@ int test(int i, int j, int (*foo)(int), int (*bar)(int, int)) i = j = i + j; } + for (i = 0, // GOOD? Currently ignoring loop heads. + j = 1; + i + j < 10; + i++, j++); + + for (i = 0, + j = 1; i < 10; i += 2, // GOOD? Currently ignoring loop heads. + j++) {} + // Mixed tabs and spaces (ugly case): 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)) (void)i, // GOOD if tab >= 4 spaces else BAD -- can't exclude w/o source code text :/ (void)j; - // One char difference (common but borderline): - - for (i = 0, // GOOD? [FALSE POSITIVE] -- can't exclude w/o source code text :/ - j = 1; - i + j < 10; - i++, j++); - - for (i = 0, - j = 1; i < 10; i += 2, // GOOD? [FALSE POSITIVE] -- can't exclude w/o source code text :/ - j++) {} - // LHS ends on same line RHS begins on: int k = (foo(