From 739804acb218010820d57303b3ae5af4ef91f836 Mon Sep 17 00:00:00 2001 From: Raul Garcia Date: Wed, 17 Oct 2018 16:24:34 -0700 Subject: [PATCH 1/9] CPP : Ill-defined for-loop (C6293) Superset of C6293, it looks for a mismatch between the initialization statement && condition and the direction of the iteration expression in a for loop. --- .gitignore | 3 + .../Likely Typos/illDefinedForLoop.c | 7 + .../Likely Typos/illDefinedForLoop.qhelp | 27 ++++ .../Likely Typos/illDefinedForLoop.ql | 102 ++++++++++++++ .../illDefinedForLoop/illDefinedForLoop.c | 89 ++++++++++++ .../illDefinedForLoop/illDefinedForLoop.cpp | 128 ++++++++++++++++++ .../illDefinedForLoop.expected | 16 +++ .../illDefinedForLoop/illDefinedForLoop.qlref | 1 + 8 files changed, 373 insertions(+) create mode 100644 cpp/ql/src/Likely Bugs/Likely Typos/illDefinedForLoop.c create mode 100644 cpp/ql/src/Likely Bugs/Likely Typos/illDefinedForLoop.qhelp create mode 100644 cpp/ql/src/Likely Bugs/Likely Typos/illDefinedForLoop.ql create mode 100644 cpp/ql/test/query-tests/Likely Bugs/Likely Typos/illDefinedForLoop/illDefinedForLoop.c create mode 100644 cpp/ql/test/query-tests/Likely Bugs/Likely Typos/illDefinedForLoop/illDefinedForLoop.cpp create mode 100644 cpp/ql/test/query-tests/Likely Bugs/Likely Typos/illDefinedForLoop/illDefinedForLoop.expected create mode 100644 cpp/ql/test/query-tests/Likely Bugs/Likely Typos/illDefinedForLoop/illDefinedForLoop.qlref diff --git a/.gitignore b/.gitignore index 7e82b2f488ca..db96e43670ff 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,6 @@ /.vs/ql/v15/Browse.VC.db /.vs/ProjectSettings.json +/.vs/slnx.sqlite-journal +/.vs/ql_6293a/v15/Browse.VC.opendb +/.vs/ql_6293a/v15/Browse.VC.db diff --git a/cpp/ql/src/Likely Bugs/Likely Typos/illDefinedForLoop.c b/cpp/ql/src/Likely Bugs/Likely Typos/illDefinedForLoop.c new file mode 100644 index 000000000000..e68abdc22031 --- /dev/null +++ b/cpp/ql/src/Likely Bugs/Likely Typos/illDefinedForLoop.c @@ -0,0 +1,7 @@ +void f() +{ + for (signed char i = 0; i < 100; i--) + { + // code ... + } +} \ No newline at end of file diff --git a/cpp/ql/src/Likely Bugs/Likely Typos/illDefinedForLoop.qhelp b/cpp/ql/src/Likely Bugs/Likely Typos/illDefinedForLoop.qhelp new file mode 100644 index 000000000000..8e99fc886600 --- /dev/null +++ b/cpp/ql/src/Likely Bugs/Likely Typos/illDefinedForLoop.qhelp @@ -0,0 +1,27 @@ + + + + +

A for-loop iteration expression goes backwards with respect of the initialization statement and condition expression.

+

This warning indicates that a for-loop might not function as intended.

+
+ + +

Verify the iteration expression on the for-loop and make sure the direction of the iteration expression is correct.

+
+ + +

In the following example, the initialization statement (i = 0) and the condition expression (i < 100) indicate that the intended iteration expression should have been incrementing, but instead a postfix decrement operator is used (i--).

+ + +

To fix this issue, change the iteration expression to match the direction of the initialization statement and the condition expression: i++.

+
+ + +
  • warning C6293: Ill-defined for-loop: counts down from minimum +
  • +
    + +
    diff --git a/cpp/ql/src/Likely Bugs/Likely Typos/illDefinedForLoop.ql b/cpp/ql/src/Likely Bugs/Likely Typos/illDefinedForLoop.ql new file mode 100644 index 000000000000..06df0141d272 --- /dev/null +++ b/cpp/ql/src/Likely Bugs/Likely Typos/illDefinedForLoop.ql @@ -0,0 +1,102 @@ +/** + * @name Ill-defined for loop + * @description A for-loop iteration expressions goes backward with respect of the initialization statement and condition expression. + * @id cpp/ill-defined-for-loop + * @kind problem + * @problem.severity warning + * @precision high + * @tags external/microsoft/6293 + * @msrc.severity important + */ +import cpp +import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis + +predicate illDefinedDecrForStmt( ForStmt forstmt, Variable v, Expr initialCondition, Expr terminalCondition ) { + v.getAnAssignedValue() = initialCondition + and + exists( + RelationalOperation rel, Expr e | + rel = forstmt.getCondition() | + e = rel.getGreaterOperand() + and v.getAnAccess() = rel.getLesserOperand() + and terminalCondition = e + ) + and + ( + exists( + PostfixDecrExpr pdec | + pdec = forstmt.getUpdate().(PostfixDecrExpr) + and pdec.getAnOperand() = v.getAnAccess() + ) or + exists( + PrefixDecrExpr pdec | + pdec = forstmt.getUpdate().(PrefixDecrExpr) + and pdec.getAnOperand() = v.getAnAccess() + ) + ) + and + upperBound(initialCondition) < lowerBound(terminalCondition) +} + +predicate illDefinedIncrForStmt( ForStmt forstmt, Variable v, Expr initialCondition, Expr terminalCondition ) { + v.getAnAssignedValue() = initialCondition + and + exists( + RelationalOperation rel, Expr e | + rel = forstmt.getCondition() | + e = rel.getLesserOperand() + and v.getAnAccess() = rel.getGreaterOperand() + and terminalCondition = e + ) + and + ( exists( PostfixIncrExpr pincr | + pincr = forstmt.getUpdate().(PostfixIncrExpr) + and + pincr.getAnOperand() = v.getAnAccess() + ) or + exists( PrefixIncrExpr pincr | + pincr = forstmt.getUpdate().(PrefixIncrExpr) + and + pincr.getAnOperand() = v.getAnAccess() + ) + ) + and + upperBound(terminalCondition) < lowerBound(initialCondition) +} + +predicate illDefinedForStmtWrongDirection( ForStmt forstmt, Variable v, Expr initialCondition, Expr terminalCondition + , boolean isIncr ) { + ( illDefinedDecrForStmt( forstmt, v, initialCondition, terminalCondition) and isIncr = false ) + or + ( illDefinedIncrForStmt( forstmt, v, initialCondition, terminalCondition) and isIncr = true) +} + +bindingset[b] +private string forLoopdirection(boolean b){ + if( b = true ) then result = "upward" + else result = "downward" +} + +bindingset[b] +private string forLoopTerminalConditionRelationship(boolean b){ + if( b = true ) then result = "lower" + else result = "higher" +} + + predicate illDefinedForStmt( ForStmt for, string message ) { + exists( + boolean isIncr, + Variable v, + Expr initialCondition, + Expr terminalCondition | + illDefinedForStmtWrongDirection(for, v, initialCondition, terminalCondition, isIncr) + and + message = "Ill-defined for-loop: a loop using variable \"" + v + "\" counts " + + forLoopdirection(isIncr) + " from a value ("+ initialCondition +"), but the terminal condition is " + + forLoopTerminalConditionRelationship(isIncr) + " (" + terminalCondition + ")." + ) +} + +from ForStmt forstmt, string message + where illDefinedForStmt(forstmt, message) +select forstmt, message diff --git a/cpp/ql/test/query-tests/Likely Bugs/Likely Typos/illDefinedForLoop/illDefinedForLoop.c b/cpp/ql/test/query-tests/Likely Bugs/Likely Typos/illDefinedForLoop/illDefinedForLoop.c new file mode 100644 index 000000000000..d66e027bdc1e --- /dev/null +++ b/cpp/ql/test/query-tests/Likely Bugs/Likely Typos/illDefinedForLoop/illDefinedForLoop.c @@ -0,0 +1,89 @@ +void Signed() +{ + signed char i; + + for (i = 0; i < 100; i--) //BUG + { + } + + for (i = 0; i < 100; i++) + { + } + + for (i = 100; i >= 0; i++) //BUG + { + } + + for (i = 100; i >= 0; i--) + { + } + +} + +void Unsigned() +{ + unsigned long i; + + for (i = 0; i < 100; i--) //BUG + { + } + + for (i = 0; i < 100; i++) + { + } + + for (i = 100; i >= 0; i++) //BUG + { + } + + for (i = 100; i >= 0; i--) + { + } +} + +void InitializationOutsideLoop() +{ + signed char i = 0; + + for (; i < 100; i--) //BUG + { + } + + i = 0; + for (; i < 100; i++) + { + } + + i = 100; + for (; i >= 0; i++) //BUG + { + } + + i = 100; + for (; i >= 0; i--) + { + } +} + +void NegativeTestCase() +{ + int i; + for (i = 0; (200 - i) < 100; i--) + { + // code ... + } +} + +void NegativeTestCaseNested() +{ + int k; + int i; + + for (k = 200; k < 300; k++) + { + for (i = 0; (k - i) < 100; i--) + { + // code ... + } + } +} diff --git a/cpp/ql/test/query-tests/Likely Bugs/Likely Typos/illDefinedForLoop/illDefinedForLoop.cpp b/cpp/ql/test/query-tests/Likely Bugs/Likely Typos/illDefinedForLoop/illDefinedForLoop.cpp new file mode 100644 index 000000000000..db6fc509055c --- /dev/null +++ b/cpp/ql/test/query-tests/Likely Bugs/Likely Typos/illDefinedForLoop/illDefinedForLoop.cpp @@ -0,0 +1,128 @@ +void Signed() +{ + signed char i; + + for (i = 0; i < 100; i--) //BUG + { + } + + for (i = 0; i < 100; i++) + { + } + + for (i = 100; i >= 0; i++) //BUG + { + } + + for (i = 100; i >= 0; i--) + { + } + +} + +void Unsigned() +{ + unsigned long i; + + for (i = 0; i < 100; i--) //BUG + { + } + + for (i = 0; i < 100; i++) + { + } + + for (i = 100; i >= 0; i++) //BUG + { + } + + for (i = 100; i >= 0; i--) + { + } +} + +void DeclarationInLoop() +{ + for (signed char i = 0; i < 100; i--) //BUG + { + } + + for (signed char i = 0; i < 100; i++) + { + } + + for (unsigned char i = 100; i >= 0; i++) //BUG + { + } + + for (unsigned char i = 100; i >= 0; i--) + { + } +} + +void SignedWithVariables() +{ + signed char i; + signed char min = 0; + signed char max = 100; + + for (i = min; i < max; i--) //BUG + { + } + + for (i = min; i < max; i++) + { + } + + for (i = max; i >= min; i++) //BUG + { + } + + for (i = max; i >= min; i--) + { + } + +} + +void InitializationOutsideLoop() +{ + signed char i = 0; + + for (; i < 100; i--) //BUG + { + } + + i = 0; + for (; i < 100; i++) + { + } + + i = 100; + for (; i >= 0; i++) //BUG + { + } + + i = 100; + for (; i >= 0; i--) + { + } +} + +void NegativeTestCase() +{ + for (int i = 0; (200 - i) < 100; i--) + { + // code ... + } +} + +void NegativeTestCaseNested() +{ + for (int k = 200; k < 300; k++) + { + for (int i = 0; (k - i) < 100; i--) + { + // code ... + } + } +} diff --git a/cpp/ql/test/query-tests/Likely Bugs/Likely Typos/illDefinedForLoop/illDefinedForLoop.expected b/cpp/ql/test/query-tests/Likely Bugs/Likely Typos/illDefinedForLoop/illDefinedForLoop.expected new file mode 100644 index 000000000000..2079abcbe2f1 --- /dev/null +++ b/cpp/ql/test/query-tests/Likely Bugs/Likely Typos/illDefinedForLoop/illDefinedForLoop.expected @@ -0,0 +1,16 @@ +| illDefinedForLoop.c:5:5:7:5 | for(...;...;...) ... | Ill-defined for-loop: a loop using variable "i" counts downward from a value (0), but the terminal condition is higher (100). | +| illDefinedForLoop.c:13:5:15:5 | for(...;...;...) ... | Ill-defined for-loop: a loop using variable "i" counts upward from a value (100), but the terminal condition is lower (0). | +| illDefinedForLoop.c:27:5:29:5 | for(...;...;...) ... | Ill-defined for-loop: a loop using variable "i" counts downward from a value (0), but the terminal condition is higher (100). | +| illDefinedForLoop.c:35:5:37:5 | for(...;...;...) ... | Ill-defined for-loop: a loop using variable "i" counts upward from a value (100), but the terminal condition is lower (0). | +| illDefinedForLoop.c:48:5:50:5 | for(...;...;...) ... | Ill-defined for-loop: a loop using variable "i" counts downward from a value (0), but the terminal condition is higher (100). | +| illDefinedForLoop.c:58:5:60:5 | for(...;...;...) ... | Ill-defined for-loop: a loop using variable "i" counts upward from a value (100), but the terminal condition is lower (0). | +| illDefinedForLoop.cpp:5:5:7:5 | for(...;...;...) ... | Ill-defined for-loop: a loop using variable "i" counts downward from a value (0), but the terminal condition is higher (100). | +| illDefinedForLoop.cpp:13:5:15:5 | for(...;...;...) ... | Ill-defined for-loop: a loop using variable "i" counts upward from a value (100), but the terminal condition is lower (0). | +| illDefinedForLoop.cpp:27:5:29:5 | for(...;...;...) ... | Ill-defined for-loop: a loop using variable "i" counts downward from a value (0), but the terminal condition is higher (100). | +| illDefinedForLoop.cpp:35:5:37:5 | for(...;...;...) ... | Ill-defined for-loop: a loop using variable "i" counts upward from a value (100), but the terminal condition is lower (0). | +| illDefinedForLoop.cpp:46:5:48:5 | for(...;...;...) ... | Ill-defined for-loop: a loop using variable "i" counts downward from a value (0), but the terminal condition is higher (100). | +| illDefinedForLoop.cpp:54:5:56:5 | for(...;...;...) ... | Ill-defined for-loop: a loop using variable "i" counts upward from a value (100), but the terminal condition is lower (0). | +| illDefinedForLoop.cpp:69:5:71:5 | for(...;...;...) ... | Ill-defined for-loop: a loop using variable "i" counts downward from a value (min), but the terminal condition is higher (max). | +| illDefinedForLoop.cpp:77:5:79:5 | for(...;...;...) ... | Ill-defined for-loop: a loop using variable "i" counts upward from a value (max), but the terminal condition is lower (min). | +| illDefinedForLoop.cpp:91:5:93:5 | for(...;...;...) ... | Ill-defined for-loop: a loop using variable "i" counts downward from a value (0), but the terminal condition is higher (100). | +| illDefinedForLoop.cpp:101:5:103:5 | for(...;...;...) ... | Ill-defined for-loop: a loop using variable "i" counts upward from a value (100), but the terminal condition is lower (0). | diff --git a/cpp/ql/test/query-tests/Likely Bugs/Likely Typos/illDefinedForLoop/illDefinedForLoop.qlref b/cpp/ql/test/query-tests/Likely Bugs/Likely Typos/illDefinedForLoop/illDefinedForLoop.qlref new file mode 100644 index 000000000000..cc5ed35c3b46 --- /dev/null +++ b/cpp/ql/test/query-tests/Likely Bugs/Likely Typos/illDefinedForLoop/illDefinedForLoop.qlref @@ -0,0 +1 @@ +Likely Bugs/Likely Typos/illDefinedForLoop.ql \ No newline at end of file From f99756c07f2362967b326b1949d310007b160715 Mon Sep 17 00:00:00 2001 From: Raul Garcia <42392023+raulgarciamsft@users.noreply.github.com> Date: Wed, 17 Oct 2018 16:27:42 -0700 Subject: [PATCH 2/9] Update .gitignore --- .gitignore | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.gitignore b/.gitignore index db96e43670ff..4b055e55a091 100644 --- a/.gitignore +++ b/.gitignore @@ -12,7 +12,3 @@ /.vs/ql/v15/Browse.VC.opendb /.vs/ql/v15/Browse.VC.db /.vs/ProjectSettings.json - -/.vs/slnx.sqlite-journal -/.vs/ql_6293a/v15/Browse.VC.opendb -/.vs/ql_6293a/v15/Browse.VC.db From 8eaba03506492d1546950fa417c73008c5cb1735 Mon Sep 17 00:00:00 2001 From: Raul Garcia <42392023+raulgarciamsft@users.noreply.github.com> Date: Wed, 17 Oct 2018 16:28:01 -0700 Subject: [PATCH 3/9] Update .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 4b055e55a091..7e82b2f488ca 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,4 @@ /.vs/ql/v15/Browse.VC.opendb /.vs/ql/v15/Browse.VC.db /.vs/ProjectSettings.json + From ce99f469a95e122a0518b5b2f4143064a9a784af Mon Sep 17 00:00:00 2001 From: Dave Bartolomeo <42150477+dave-bartolomeo@users.noreply.github.com> Date: Thu, 18 Oct 2018 12:02:06 -0700 Subject: [PATCH 4/9] Update cpp/ql/src/Likely Bugs/Likely Typos/illDefinedForLoop.ql --- cpp/ql/src/Likely Bugs/Likely Typos/illDefinedForLoop.ql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/ql/src/Likely Bugs/Likely Typos/illDefinedForLoop.ql b/cpp/ql/src/Likely Bugs/Likely Typos/illDefinedForLoop.ql index 06df0141d272..8f35d6f095fb 100644 --- a/cpp/ql/src/Likely Bugs/Likely Typos/illDefinedForLoop.ql +++ b/cpp/ql/src/Likely Bugs/Likely Typos/illDefinedForLoop.ql @@ -1,6 +1,6 @@ /** * @name Ill-defined for loop - * @description A for-loop iteration expressions goes backward with respect of the initialization statement and condition expression. + * @description A for-loop iteration expression goes backward with respect of the initialization statement and condition expression. * @id cpp/ill-defined-for-loop * @kind problem * @problem.severity warning From e2fcaa9e20c910c6105b66ede6befa4ad52da0d8 Mon Sep 17 00:00:00 2001 From: Raul Garcia Date: Thu, 18 Oct 2018 14:44:24 -0700 Subject: [PATCH 5/9] Fixing typos & implementing the PR feedback --- .gitignore | 3 + .../Likely Typos/illDefinedForLoop.qhelp | 2 +- .../Likely Typos/illDefinedForLoop.ql | 80 +++++++++++-------- .../illDefinedForLoop/illDefinedForLoop.cpp | 68 ++++++++++++++-- .../illDefinedForLoop.expected | 6 ++ 5 files changed, 116 insertions(+), 43 deletions(-) diff --git a/.gitignore b/.gitignore index 7e82b2f488ca..3327cd9096bd 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,6 @@ /.vs/ql/v15/Browse.VC.db /.vs/ProjectSettings.json +/.vs/ql_6293a/v15/Browse.VC.opendb +/.vs/ql_6293a/v15/Browse.VC.db +/.vs/ql_6293a/v15/.suo diff --git a/cpp/ql/src/Likely Bugs/Likely Typos/illDefinedForLoop.qhelp b/cpp/ql/src/Likely Bugs/Likely Typos/illDefinedForLoop.qhelp index 8e99fc886600..8440fdcf5441 100644 --- a/cpp/ql/src/Likely Bugs/Likely Typos/illDefinedForLoop.qhelp +++ b/cpp/ql/src/Likely Bugs/Likely Typos/illDefinedForLoop.qhelp @@ -9,7 +9,7 @@ -

    Verify the iteration expression on the for-loop and make sure the direction of the iteration expression is correct.

    +

    To fix this issue, check that the loop condition is correct and change the iteration expression to match.

    diff --git a/cpp/ql/src/Likely Bugs/Likely Typos/illDefinedForLoop.ql b/cpp/ql/src/Likely Bugs/Likely Typos/illDefinedForLoop.ql index 8f35d6f095fb..f0aa2a6e4c6e 100644 --- a/cpp/ql/src/Likely Bugs/Likely Typos/illDefinedForLoop.ql +++ b/cpp/ql/src/Likely Bugs/Likely Typos/illDefinedForLoop.ql @@ -10,58 +10,56 @@ */ import cpp import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis +import semmle.code.cpp.dataflow.DataFlow predicate illDefinedDecrForStmt( ForStmt forstmt, Variable v, Expr initialCondition, Expr terminalCondition ) { - v.getAnAssignedValue() = initialCondition + v.getAnAssignedValue() = initialCondition and exists( - RelationalOperation rel, Expr e | + RelationalOperation rel | rel = forstmt.getCondition() | - e = rel.getGreaterOperand() + terminalCondition = rel.getGreaterOperand() and v.getAnAccess() = rel.getLesserOperand() - and terminalCondition = e - ) - and - ( - exists( - PostfixDecrExpr pdec | - pdec = forstmt.getUpdate().(PostfixDecrExpr) - and pdec.getAnOperand() = v.getAnAccess() - ) or - exists( - PrefixDecrExpr pdec | - pdec = forstmt.getUpdate().(PrefixDecrExpr) - and pdec.getAnOperand() = v.getAnAccess() + and + DataFlow::localFlowStep(DataFlow::exprNode(initialCondition), DataFlow::exprNode(rel.getLesserOperand())) ) + and + exists( + DecrementOperation dec | + dec = forstmt.getUpdate().(DecrementOperation) + and dec.getAnOperand() = v.getAnAccess() ) and - upperBound(initialCondition) < lowerBound(terminalCondition) + ( + ( upperBound(initialCondition) < lowerBound(terminalCondition) ) + or + ( forstmt.conditionAlwaysFalse() or forstmt.conditionAlwaysTrue() ) + ) } predicate illDefinedIncrForStmt( ForStmt forstmt, Variable v, Expr initialCondition, Expr terminalCondition ) { v.getAnAssignedValue() = initialCondition and exists( - RelationalOperation rel, Expr e | + RelationalOperation rel | rel = forstmt.getCondition() | - e = rel.getLesserOperand() + terminalCondition = rel.getLesserOperand() and v.getAnAccess() = rel.getGreaterOperand() - and terminalCondition = e + and + DataFlow::localFlowStep(DataFlow::exprNode(initialCondition), DataFlow::exprNode(rel.getGreaterOperand())) ) and - ( exists( PostfixIncrExpr pincr | - pincr = forstmt.getUpdate().(PostfixIncrExpr) - and - pincr.getAnOperand() = v.getAnAccess() - ) or - exists( PrefixIncrExpr pincr | - pincr = forstmt.getUpdate().(PrefixIncrExpr) - and - pincr.getAnOperand() = v.getAnAccess() - ) + exists( IncrementOperation incr | + incr = forstmt.getUpdate().(IncrementOperation) + and + incr.getAnOperand() = v.getAnAccess() ) and - upperBound(terminalCondition) < lowerBound(initialCondition) + ( + ( upperBound(terminalCondition) < lowerBound(initialCondition)) + or + ( forstmt.conditionAlwaysFalse() or forstmt.conditionAlwaysTrue()) + ) } predicate illDefinedForStmtWrongDirection( ForStmt forstmt, Variable v, Expr initialCondition, Expr terminalCondition @@ -91,9 +89,23 @@ private string forLoopTerminalConditionRelationship(boolean b){ Expr terminalCondition | illDefinedForStmtWrongDirection(for, v, initialCondition, terminalCondition, isIncr) and - message = "Ill-defined for-loop: a loop using variable \"" + v + "\" counts " - + forLoopdirection(isIncr) + " from a value ("+ initialCondition +"), but the terminal condition is " - + forLoopTerminalConditionRelationship(isIncr) + " (" + terminalCondition + ")." + if( for.conditionAlwaysFalse() ) then + ( + message = "Ill-defined for-loop: a loop using variable \"" + v + "\" counts " + + forLoopdirection(isIncr) + " from a value ("+ initialCondition +"), but the terminal condition is always false." + ) + else if + ( + for.conditionAlwaysTrue() ) then ( + message = "Ill-defined for-loop: a loop using variable \"" + v + "\" counts " + + forLoopdirection(isIncr) + " from a value ("+ initialCondition +"), but the terminal condition is always true." + ) + else + ( + message = "Ill-defined for-loop: a loop using variable \"" + v + "\" counts " + + forLoopdirection(isIncr) + " from a value ("+ initialCondition +"), but the terminal condition is " + + forLoopTerminalConditionRelationship(isIncr) + " (" + terminalCondition + ")." + ) ) } diff --git a/cpp/ql/test/query-tests/Likely Bugs/Likely Typos/illDefinedForLoop/illDefinedForLoop.cpp b/cpp/ql/test/query-tests/Likely Bugs/Likely Typos/illDefinedForLoop/illDefinedForLoop.cpp index db6fc509055c..15e5c3331023 100644 --- a/cpp/ql/test/query-tests/Likely Bugs/Likely Typos/illDefinedForLoop/illDefinedForLoop.cpp +++ b/cpp/ql/test/query-tests/Likely Bugs/Likely Typos/illDefinedForLoop/illDefinedForLoop.cpp @@ -43,19 +43,19 @@ void Unsigned() void DeclarationInLoop() { - for (signed char i = 0; i < 100; i--) //BUG + for (signed char i = 0; i < 100; --i) //BUG { } - for (signed char i = 0; i < 100; i++) + for (signed char i = 0; i < 100; ++i) { } - for (unsigned char i = 100; i >= 0; i++) //BUG + for (unsigned char i = 100; i >= 0; ++i) //BUG { } - for (unsigned char i = 100; i >= 0; i--) + for (unsigned char i = 100; i >= 0; --i) { } } @@ -88,22 +88,56 @@ void InitializationOutsideLoop() { signed char i = 0; - for (; i < 100; i--) //BUG + for (; i < 100; --i) //BUG { } i = 0; - for (; i < 100; i++) + for (; i < 100; ++i) { } i = 100; - for (; i >= 0; i++) //BUG + for (; i >= 0; ++i) //BUG { } i = 100; - for (; i >= 0; i--) + for (; i >= 0; --i) + { + } +} + + +void InvalidCondition() +{ + signed char i; + signed char min = 0; + signed char max = 100; + + for (i = max; i < min; i--) //BUG + { + } + + for (i = min; i > max; i++) //BUG + { + } +} + +void InvalidConditionUnsignedCornerCase() +{ + unsigned char i; + unsigned char min = 0; + unsigned char max = 100; + + for (i = 100; i < 0; i--) //BUG + { + } + + // Limitation. + // Currently odasa will not detect this for-loop condition as always true + // The rule will still detect the mismatch iterator, but the error message may change in the future. + for (i = 200; i >= 0; i++) //BUG { } } @@ -126,3 +160,21 @@ void NegativeTestCaseNested() } } } + +////////////////////////////////////// +// Query limitation: +// +// The following test cases are bugs, +// but will not be found due to the itearion expression +// not being a prefix or postfix increment/decrement +// +void FalseNegativeTestCases() +{ + for (int i = 0; i < 10; i = i - 1) {} + // For comparison + for (int i = 0; i < 10; i-- ) {} // BUG + + for (int i = 100; i > 0; i += 2) {} + // For comparison + for (int i = 100; i > 0; i ++ ) {} // BUG +} \ No newline at end of file diff --git a/cpp/ql/test/query-tests/Likely Bugs/Likely Typos/illDefinedForLoop/illDefinedForLoop.expected b/cpp/ql/test/query-tests/Likely Bugs/Likely Typos/illDefinedForLoop/illDefinedForLoop.expected index 2079abcbe2f1..5e2b2bae9a02 100644 --- a/cpp/ql/test/query-tests/Likely Bugs/Likely Typos/illDefinedForLoop/illDefinedForLoop.expected +++ b/cpp/ql/test/query-tests/Likely Bugs/Likely Typos/illDefinedForLoop/illDefinedForLoop.expected @@ -14,3 +14,9 @@ | illDefinedForLoop.cpp:77:5:79:5 | for(...;...;...) ... | Ill-defined for-loop: a loop using variable "i" counts upward from a value (max), but the terminal condition is lower (min). | | illDefinedForLoop.cpp:91:5:93:5 | for(...;...;...) ... | Ill-defined for-loop: a loop using variable "i" counts downward from a value (0), but the terminal condition is higher (100). | | illDefinedForLoop.cpp:101:5:103:5 | for(...;...;...) ... | Ill-defined for-loop: a loop using variable "i" counts upward from a value (100), but the terminal condition is lower (0). | +| illDefinedForLoop.cpp:118:5:120:5 | for(...;...;...) ... | Ill-defined for-loop: a loop using variable "i" counts downward from a value (max), but the terminal condition is always false. | +| illDefinedForLoop.cpp:122:5:124:5 | for(...;...;...) ... | Ill-defined for-loop: a loop using variable "i" counts upward from a value (min), but the terminal condition is always false. | +| illDefinedForLoop.cpp:133:5:135:5 | for(...;...;...) ... | Ill-defined for-loop: a loop using variable "i" counts downward from a value (100), but the terminal condition is always false. | +| illDefinedForLoop.cpp:140:5:142:5 | for(...;...;...) ... | Ill-defined for-loop: a loop using variable "i" counts upward from a value (200), but the terminal condition is lower (0). | +| illDefinedForLoop.cpp:175:5:175:36 | for(...;...;...) ... | Ill-defined for-loop: a loop using variable "i" counts downward from a value (0), but the terminal condition is higher (10). | +| illDefinedForLoop.cpp:179:5:179:38 | for(...;...;...) ... | Ill-defined for-loop: a loop using variable "i" counts upward from a value (100), but the terminal condition is lower (0). | From 8138a3be07bf38be2c9844b073697ca8f95d6cd8 Mon Sep 17 00:00:00 2001 From: Raul Garcia <42392023+raulgarciamsft@users.noreply.github.com> Date: Thu, 18 Oct 2018 14:45:09 -0700 Subject: [PATCH 6/9] Update .gitignore --- .gitignore | 3 --- 1 file changed, 3 deletions(-) diff --git a/.gitignore b/.gitignore index 3327cd9096bd..7e82b2f488ca 100644 --- a/.gitignore +++ b/.gitignore @@ -13,6 +13,3 @@ /.vs/ql/v15/Browse.VC.db /.vs/ProjectSettings.json -/.vs/ql_6293a/v15/Browse.VC.opendb -/.vs/ql_6293a/v15/Browse.VC.db -/.vs/ql_6293a/v15/.suo From 2f4da8841fc7dee399a237dd10295b669d3feac5 Mon Sep 17 00:00:00 2001 From: Raul Garcia Date: Fri, 19 Oct 2018 15:21:56 -0700 Subject: [PATCH 7/9] Changing the name (file & tags) to match the JS version. --- ...dForLoop.c => inconsistentLoopDirection.c} | 0 ....qhelp => inconsistentLoopDirection.qhelp} | 2 +- ...orLoop.ql => inconsistentLoopDirection.ql} | 10 +++++---- .../illDefinedForLoop.expected | 22 ------------------- .../illDefinedForLoop/illDefinedForLoop.qlref | 1 - .../inconsistentLoopDirection.c} | 0 .../inconsistentLoopDirection.cpp} | 2 +- .../inconsistentLoopDirection.expected | 22 +++++++++++++++++++ .../inconsistentLoopDirection.qlref | 1 + 9 files changed, 31 insertions(+), 29 deletions(-) rename cpp/ql/src/Likely Bugs/Likely Typos/{illDefinedForLoop.c => inconsistentLoopDirection.c} (100%) rename cpp/ql/src/Likely Bugs/Likely Typos/{illDefinedForLoop.qhelp => inconsistentLoopDirection.qhelp} (96%) rename cpp/ql/src/Likely Bugs/Likely Typos/{illDefinedForLoop.ql => inconsistentLoopDirection.ql} (94%) delete mode 100644 cpp/ql/test/query-tests/Likely Bugs/Likely Typos/illDefinedForLoop/illDefinedForLoop.expected delete mode 100644 cpp/ql/test/query-tests/Likely Bugs/Likely Typos/illDefinedForLoop/illDefinedForLoop.qlref rename cpp/ql/test/query-tests/Likely Bugs/Likely Typos/{illDefinedForLoop/illDefinedForLoop.c => inconsistentLoopDirection/inconsistentLoopDirection.c} (100%) rename cpp/ql/test/query-tests/Likely Bugs/Likely Typos/{illDefinedForLoop/illDefinedForLoop.cpp => inconsistentLoopDirection/inconsistentLoopDirection.cpp} (98%) create mode 100644 cpp/ql/test/query-tests/Likely Bugs/Likely Typos/inconsistentLoopDirection/inconsistentLoopDirection.expected create mode 100644 cpp/ql/test/query-tests/Likely Bugs/Likely Typos/inconsistentLoopDirection/inconsistentLoopDirection.qlref diff --git a/cpp/ql/src/Likely Bugs/Likely Typos/illDefinedForLoop.c b/cpp/ql/src/Likely Bugs/Likely Typos/inconsistentLoopDirection.c similarity index 100% rename from cpp/ql/src/Likely Bugs/Likely Typos/illDefinedForLoop.c rename to cpp/ql/src/Likely Bugs/Likely Typos/inconsistentLoopDirection.c diff --git a/cpp/ql/src/Likely Bugs/Likely Typos/illDefinedForLoop.qhelp b/cpp/ql/src/Likely Bugs/Likely Typos/inconsistentLoopDirection.qhelp similarity index 96% rename from cpp/ql/src/Likely Bugs/Likely Typos/illDefinedForLoop.qhelp rename to cpp/ql/src/Likely Bugs/Likely Typos/inconsistentLoopDirection.qhelp index 8440fdcf5441..406019602f7a 100644 --- a/cpp/ql/src/Likely Bugs/Likely Typos/illDefinedForLoop.qhelp +++ b/cpp/ql/src/Likely Bugs/Likely Typos/inconsistentLoopDirection.qhelp @@ -14,7 +14,7 @@

    In the following example, the initialization statement (i = 0) and the condition expression (i < 100) indicate that the intended iteration expression should have been incrementing, but instead a postfix decrement operator is used (i--).

    - +

    To fix this issue, change the iteration expression to match the direction of the initialization statement and the condition expression: i++.

    diff --git a/cpp/ql/src/Likely Bugs/Likely Typos/illDefinedForLoop.ql b/cpp/ql/src/Likely Bugs/Likely Typos/inconsistentLoopDirection.ql similarity index 94% rename from cpp/ql/src/Likely Bugs/Likely Typos/illDefinedForLoop.ql rename to cpp/ql/src/Likely Bugs/Likely Typos/inconsistentLoopDirection.ql index f0aa2a6e4c6e..a12cbe08b030 100644 --- a/cpp/ql/src/Likely Bugs/Likely Typos/illDefinedForLoop.ql +++ b/cpp/ql/src/Likely Bugs/Likely Typos/inconsistentLoopDirection.ql @@ -1,11 +1,13 @@ /** - * @name Ill-defined for loop + * @name Inconsistent direction of for loop * @description A for-loop iteration expression goes backward with respect of the initialization statement and condition expression. - * @id cpp/ill-defined-for-loop * @kind problem - * @problem.severity warning + * @problem.severity error * @precision high - * @tags external/microsoft/6293 + * @id cpp/inconsistent-loop-direction + * @tags correctness + * external/cwe/cwe-835 + * external/microsoft/6293 * @msrc.severity important */ import cpp diff --git a/cpp/ql/test/query-tests/Likely Bugs/Likely Typos/illDefinedForLoop/illDefinedForLoop.expected b/cpp/ql/test/query-tests/Likely Bugs/Likely Typos/illDefinedForLoop/illDefinedForLoop.expected deleted file mode 100644 index 5e2b2bae9a02..000000000000 --- a/cpp/ql/test/query-tests/Likely Bugs/Likely Typos/illDefinedForLoop/illDefinedForLoop.expected +++ /dev/null @@ -1,22 +0,0 @@ -| illDefinedForLoop.c:5:5:7:5 | for(...;...;...) ... | Ill-defined for-loop: a loop using variable "i" counts downward from a value (0), but the terminal condition is higher (100). | -| illDefinedForLoop.c:13:5:15:5 | for(...;...;...) ... | Ill-defined for-loop: a loop using variable "i" counts upward from a value (100), but the terminal condition is lower (0). | -| illDefinedForLoop.c:27:5:29:5 | for(...;...;...) ... | Ill-defined for-loop: a loop using variable "i" counts downward from a value (0), but the terminal condition is higher (100). | -| illDefinedForLoop.c:35:5:37:5 | for(...;...;...) ... | Ill-defined for-loop: a loop using variable "i" counts upward from a value (100), but the terminal condition is lower (0). | -| illDefinedForLoop.c:48:5:50:5 | for(...;...;...) ... | Ill-defined for-loop: a loop using variable "i" counts downward from a value (0), but the terminal condition is higher (100). | -| illDefinedForLoop.c:58:5:60:5 | for(...;...;...) ... | Ill-defined for-loop: a loop using variable "i" counts upward from a value (100), but the terminal condition is lower (0). | -| illDefinedForLoop.cpp:5:5:7:5 | for(...;...;...) ... | Ill-defined for-loop: a loop using variable "i" counts downward from a value (0), but the terminal condition is higher (100). | -| illDefinedForLoop.cpp:13:5:15:5 | for(...;...;...) ... | Ill-defined for-loop: a loop using variable "i" counts upward from a value (100), but the terminal condition is lower (0). | -| illDefinedForLoop.cpp:27:5:29:5 | for(...;...;...) ... | Ill-defined for-loop: a loop using variable "i" counts downward from a value (0), but the terminal condition is higher (100). | -| illDefinedForLoop.cpp:35:5:37:5 | for(...;...;...) ... | Ill-defined for-loop: a loop using variable "i" counts upward from a value (100), but the terminal condition is lower (0). | -| illDefinedForLoop.cpp:46:5:48:5 | for(...;...;...) ... | Ill-defined for-loop: a loop using variable "i" counts downward from a value (0), but the terminal condition is higher (100). | -| illDefinedForLoop.cpp:54:5:56:5 | for(...;...;...) ... | Ill-defined for-loop: a loop using variable "i" counts upward from a value (100), but the terminal condition is lower (0). | -| illDefinedForLoop.cpp:69:5:71:5 | for(...;...;...) ... | Ill-defined for-loop: a loop using variable "i" counts downward from a value (min), but the terminal condition is higher (max). | -| illDefinedForLoop.cpp:77:5:79:5 | for(...;...;...) ... | Ill-defined for-loop: a loop using variable "i" counts upward from a value (max), but the terminal condition is lower (min). | -| illDefinedForLoop.cpp:91:5:93:5 | for(...;...;...) ... | Ill-defined for-loop: a loop using variable "i" counts downward from a value (0), but the terminal condition is higher (100). | -| illDefinedForLoop.cpp:101:5:103:5 | for(...;...;...) ... | Ill-defined for-loop: a loop using variable "i" counts upward from a value (100), but the terminal condition is lower (0). | -| illDefinedForLoop.cpp:118:5:120:5 | for(...;...;...) ... | Ill-defined for-loop: a loop using variable "i" counts downward from a value (max), but the terminal condition is always false. | -| illDefinedForLoop.cpp:122:5:124:5 | for(...;...;...) ... | Ill-defined for-loop: a loop using variable "i" counts upward from a value (min), but the terminal condition is always false. | -| illDefinedForLoop.cpp:133:5:135:5 | for(...;...;...) ... | Ill-defined for-loop: a loop using variable "i" counts downward from a value (100), but the terminal condition is always false. | -| illDefinedForLoop.cpp:140:5:142:5 | for(...;...;...) ... | Ill-defined for-loop: a loop using variable "i" counts upward from a value (200), but the terminal condition is lower (0). | -| illDefinedForLoop.cpp:175:5:175:36 | for(...;...;...) ... | Ill-defined for-loop: a loop using variable "i" counts downward from a value (0), but the terminal condition is higher (10). | -| illDefinedForLoop.cpp:179:5:179:38 | for(...;...;...) ... | Ill-defined for-loop: a loop using variable "i" counts upward from a value (100), but the terminal condition is lower (0). | diff --git a/cpp/ql/test/query-tests/Likely Bugs/Likely Typos/illDefinedForLoop/illDefinedForLoop.qlref b/cpp/ql/test/query-tests/Likely Bugs/Likely Typos/illDefinedForLoop/illDefinedForLoop.qlref deleted file mode 100644 index cc5ed35c3b46..000000000000 --- a/cpp/ql/test/query-tests/Likely Bugs/Likely Typos/illDefinedForLoop/illDefinedForLoop.qlref +++ /dev/null @@ -1 +0,0 @@ -Likely Bugs/Likely Typos/illDefinedForLoop.ql \ No newline at end of file diff --git a/cpp/ql/test/query-tests/Likely Bugs/Likely Typos/illDefinedForLoop/illDefinedForLoop.c b/cpp/ql/test/query-tests/Likely Bugs/Likely Typos/inconsistentLoopDirection/inconsistentLoopDirection.c similarity index 100% rename from cpp/ql/test/query-tests/Likely Bugs/Likely Typos/illDefinedForLoop/illDefinedForLoop.c rename to cpp/ql/test/query-tests/Likely Bugs/Likely Typos/inconsistentLoopDirection/inconsistentLoopDirection.c diff --git a/cpp/ql/test/query-tests/Likely Bugs/Likely Typos/illDefinedForLoop/illDefinedForLoop.cpp b/cpp/ql/test/query-tests/Likely Bugs/Likely Typos/inconsistentLoopDirection/inconsistentLoopDirection.cpp similarity index 98% rename from cpp/ql/test/query-tests/Likely Bugs/Likely Typos/illDefinedForLoop/illDefinedForLoop.cpp rename to cpp/ql/test/query-tests/Likely Bugs/Likely Typos/inconsistentLoopDirection/inconsistentLoopDirection.cpp index 15e5c3331023..e6e743382ed8 100644 --- a/cpp/ql/test/query-tests/Likely Bugs/Likely Typos/illDefinedForLoop/illDefinedForLoop.cpp +++ b/cpp/ql/test/query-tests/Likely Bugs/Likely Typos/inconsistentLoopDirection/inconsistentLoopDirection.cpp @@ -144,7 +144,7 @@ void InvalidConditionUnsignedCornerCase() void NegativeTestCase() { - for (int i = 0; (200 - i) < 100; i--) + for (int i = 0; (100 - i) < 200; i--) { // code ... } diff --git a/cpp/ql/test/query-tests/Likely Bugs/Likely Typos/inconsistentLoopDirection/inconsistentLoopDirection.expected b/cpp/ql/test/query-tests/Likely Bugs/Likely Typos/inconsistentLoopDirection/inconsistentLoopDirection.expected new file mode 100644 index 000000000000..f5ff346271f0 --- /dev/null +++ b/cpp/ql/test/query-tests/Likely Bugs/Likely Typos/inconsistentLoopDirection/inconsistentLoopDirection.expected @@ -0,0 +1,22 @@ +| inconsistentLoopDirection.c:5:5:7:5 | for(...;...;...) ... | Ill-defined for-loop: a loop using variable "i" counts downward from a value (0), but the terminal condition is higher (100). | +| inconsistentLoopDirection.c:13:5:15:5 | for(...;...;...) ... | Ill-defined for-loop: a loop using variable "i" counts upward from a value (100), but the terminal condition is lower (0). | +| inconsistentLoopDirection.c:27:5:29:5 | for(...;...;...) ... | Ill-defined for-loop: a loop using variable "i" counts downward from a value (0), but the terminal condition is higher (100). | +| inconsistentLoopDirection.c:35:5:37:5 | for(...;...;...) ... | Ill-defined for-loop: a loop using variable "i" counts upward from a value (100), but the terminal condition is lower (0). | +| inconsistentLoopDirection.c:48:5:50:5 | for(...;...;...) ... | Ill-defined for-loop: a loop using variable "i" counts downward from a value (0), but the terminal condition is higher (100). | +| inconsistentLoopDirection.c:58:5:60:5 | for(...;...;...) ... | Ill-defined for-loop: a loop using variable "i" counts upward from a value (100), but the terminal condition is lower (0). | +| inconsistentLoopDirection.cpp:5:5:7:5 | for(...;...;...) ... | Ill-defined for-loop: a loop using variable "i" counts downward from a value (0), but the terminal condition is higher (100). | +| inconsistentLoopDirection.cpp:13:5:15:5 | for(...;...;...) ... | Ill-defined for-loop: a loop using variable "i" counts upward from a value (100), but the terminal condition is lower (0). | +| inconsistentLoopDirection.cpp:27:5:29:5 | for(...;...;...) ... | Ill-defined for-loop: a loop using variable "i" counts downward from a value (0), but the terminal condition is higher (100). | +| inconsistentLoopDirection.cpp:35:5:37:5 | for(...;...;...) ... | Ill-defined for-loop: a loop using variable "i" counts upward from a value (100), but the terminal condition is lower (0). | +| inconsistentLoopDirection.cpp:46:5:48:5 | for(...;...;...) ... | Ill-defined for-loop: a loop using variable "i" counts downward from a value (0), but the terminal condition is higher (100). | +| inconsistentLoopDirection.cpp:54:5:56:5 | for(...;...;...) ... | Ill-defined for-loop: a loop using variable "i" counts upward from a value (100), but the terminal condition is lower (0). | +| inconsistentLoopDirection.cpp:69:5:71:5 | for(...;...;...) ... | Ill-defined for-loop: a loop using variable "i" counts downward from a value (min), but the terminal condition is higher (max). | +| inconsistentLoopDirection.cpp:77:5:79:5 | for(...;...;...) ... | Ill-defined for-loop: a loop using variable "i" counts upward from a value (max), but the terminal condition is lower (min). | +| inconsistentLoopDirection.cpp:91:5:93:5 | for(...;...;...) ... | Ill-defined for-loop: a loop using variable "i" counts downward from a value (0), but the terminal condition is higher (100). | +| inconsistentLoopDirection.cpp:101:5:103:5 | for(...;...;...) ... | Ill-defined for-loop: a loop using variable "i" counts upward from a value (100), but the terminal condition is lower (0). | +| inconsistentLoopDirection.cpp:118:5:120:5 | for(...;...;...) ... | Ill-defined for-loop: a loop using variable "i" counts downward from a value (max), but the terminal condition is always false. | +| inconsistentLoopDirection.cpp:122:5:124:5 | for(...;...;...) ... | Ill-defined for-loop: a loop using variable "i" counts upward from a value (min), but the terminal condition is always false. | +| inconsistentLoopDirection.cpp:133:5:135:5 | for(...;...;...) ... | Ill-defined for-loop: a loop using variable "i" counts downward from a value (100), but the terminal condition is always false. | +| inconsistentLoopDirection.cpp:140:5:142:5 | for(...;...;...) ... | Ill-defined for-loop: a loop using variable "i" counts upward from a value (200), but the terminal condition is lower (0). | +| inconsistentLoopDirection.cpp:175:5:175:36 | for(...;...;...) ... | Ill-defined for-loop: a loop using variable "i" counts downward from a value (0), but the terminal condition is higher (10). | +| inconsistentLoopDirection.cpp:179:5:179:38 | for(...;...;...) ... | Ill-defined for-loop: a loop using variable "i" counts upward from a value (100), but the terminal condition is lower (0). | diff --git a/cpp/ql/test/query-tests/Likely Bugs/Likely Typos/inconsistentLoopDirection/inconsistentLoopDirection.qlref b/cpp/ql/test/query-tests/Likely Bugs/Likely Typos/inconsistentLoopDirection/inconsistentLoopDirection.qlref new file mode 100644 index 000000000000..af5f0a899cbd --- /dev/null +++ b/cpp/ql/test/query-tests/Likely Bugs/Likely Typos/inconsistentLoopDirection/inconsistentLoopDirection.qlref @@ -0,0 +1 @@ +Likely Bugs/Likely Typos/inconsistentLoopDirection.ql \ No newline at end of file From a04eb53189cb7af8f8c000f711251ddfe57edc16 Mon Sep 17 00:00:00 2001 From: Raul Garcia Date: Wed, 24 Oct 2018 15:22:53 -0700 Subject: [PATCH 8/9] Documentation bug fix. Encoding the "<" character --- .gitignore | 3 +++ .../Likely Bugs/Likely Typos/inconsistentLoopDirection.qhelp | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 7e82b2f488ca..3327cd9096bd 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,6 @@ /.vs/ql/v15/Browse.VC.db /.vs/ProjectSettings.json +/.vs/ql_6293a/v15/Browse.VC.opendb +/.vs/ql_6293a/v15/Browse.VC.db +/.vs/ql_6293a/v15/.suo diff --git a/cpp/ql/src/Likely Bugs/Likely Typos/inconsistentLoopDirection.qhelp b/cpp/ql/src/Likely Bugs/Likely Typos/inconsistentLoopDirection.qhelp index 406019602f7a..fd28b37d878d 100644 --- a/cpp/ql/src/Likely Bugs/Likely Typos/inconsistentLoopDirection.qhelp +++ b/cpp/ql/src/Likely Bugs/Likely Typos/inconsistentLoopDirection.qhelp @@ -13,7 +13,7 @@ -

    In the following example, the initialization statement (i = 0) and the condition expression (i < 100) indicate that the intended iteration expression should have been incrementing, but instead a postfix decrement operator is used (i--).

    +

    In the following example, the initialization statement (i = 0) and the condition expression (i < 100) indicate that the intended iteration expression should have been incrementing, but instead a postfix decrement operator is used (i--).

    To fix this issue, change the iteration expression to match the direction of the initialization statement and the condition expression: i++.

    From e1efcb0b2680a709a5d632648b8420616ea68950 Mon Sep 17 00:00:00 2001 From: Raul Garcia <42392023+raulgarciamsft@users.noreply.github.com> Date: Wed, 24 Oct 2018 15:23:40 -0700 Subject: [PATCH 9/9] Update .gitignore --- .gitignore | 3 --- 1 file changed, 3 deletions(-) diff --git a/.gitignore b/.gitignore index 3327cd9096bd..7e82b2f488ca 100644 --- a/.gitignore +++ b/.gitignore @@ -13,6 +13,3 @@ /.vs/ql/v15/Browse.VC.db /.vs/ProjectSettings.json -/.vs/ql_6293a/v15/Browse.VC.opendb -/.vs/ql_6293a/v15/Browse.VC.db -/.vs/ql_6293a/v15/.suo