diff options
2 files changed, 39 insertions, 15 deletions
diff --git a/codan/org.eclipse.cdt.codan.checkers/src/org/eclipse/cdt/codan/internal/checkers/StatementHasNoEffectChecker.java b/codan/org.eclipse.cdt.codan.checkers/src/org/eclipse/cdt/codan/internal/checkers/StatementHasNoEffectChecker.java index 91831ed46ce..08b13ed9036 100644 --- a/codan/org.eclipse.cdt.codan.checkers/src/org/eclipse/cdt/codan/internal/checkers/StatementHasNoEffectChecker.java +++ b/codan/org.eclipse.cdt.codan.checkers/src/org/eclipse/cdt/codan/internal/checkers/StatementHasNoEffectChecker.java @@ -56,18 +56,44 @@ public class StatementHasNoEffectChecker extends AbstractIndexAstChecker { public int visit(IASTStatement stmt) { if (stmt instanceof IASTExpressionStatement) { IASTExpression expression = ((IASTExpressionStatement) stmt).getExpression(); - if (hasNoEffect(expression)) { + if (hasNoEffect(expression) ) { + if (isLastExpressionInStatementExpression(expression)) + return PROCESS_SKIP; if (!shouldReportInMacro() && CxxAstUtils.isInMacro(expression)) return PROCESS_SKIP; String arg = expression.getRawSignature(); - if (!isFilteredArg(arg)) - reportProblem(ER_ID, stmt, arg); + if (isFilteredArg(arg)) + return PROCESS_SKIP; + reportProblem(ER_ID, stmt, arg); } return PROCESS_SKIP; } return PROCESS_CONTINUE; } + /* + * Checks to see if the statement is the last one in a GNU Statement-Expression + * as these become the expression part of another statement and the test may generate + * false positives otherwise + */ + private boolean isLastExpressionInStatementExpression(IASTExpression e) { + // Check if it is part of GNU compound stmt expression i.e. ({int a; foo(a); a;}) + IASTNode stmt = e.getParent(); + if (stmt instanceof IASTExpressionStatement) { + IASTNode parentComp = stmt.getParent(); + if (parentComp instanceof IASTCompoundStatement) { + IASTNode parentStmtExpr = parentComp.getParent(); + if (parentStmtExpr instanceof IGNUASTCompoundStatementExpression) { + // Are we evaluating the last statement in the list? + IASTStatement childlist[] = ((IASTCompoundStatement) parentComp).getStatements(); + if (stmt == childlist[childlist.length-1]) + return true; + } + } + } + return false; + } + /** * We consider has not effect binary statements without assignment and * unary statement which is not dec and inc. If operator is overloaded @@ -109,17 +135,6 @@ public class StatementHasNoEffectChecker extends AbstractIndexAstChecker { } // simply a; if (e instanceof IASTIdExpression) { - // check if it is part of GNU comp stmt expression i.e. ({foo();a;}) - IASTNode parent = e.getParent(); - if (parent instanceof IASTExpressionStatement) { - IASTNode parent2 = parent.getParent(); - if (parent2 instanceof IASTCompoundStatement) { - IASTNode parent3 = parent2.getParent(); - if (parent3 instanceof IGNUASTCompoundStatementExpression) { - return false; - } - } - } return true; } return false; diff --git a/codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/internal/checkers/StatementHasNoEffectCheckerTest.java b/codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/internal/checkers/StatementHasNoEffectCheckerTest.java index 80481aae626..b9c30290bf1 100644 --- a/codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/internal/checkers/StatementHasNoEffectCheckerTest.java +++ b/codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/internal/checkers/StatementHasNoEffectCheckerTest.java @@ -88,13 +88,22 @@ public class StatementHasNoEffectCheckerTest extends CheckerTestCase { // main() { // int a=({foo();a;}); // no error here on line 2 + // char *p=({char s[]="Some string";&s[0];}); // no error here on line 3 // } - public void testGNUExpressionCompoundStmt() { + public void testGNUExpressionCompoundStmtFalsePositives() { loadCodeAndRun(getAboveComment()); checkNoErrors(); } // main() { + // int z=({int a=0; +a; a;}) // error here on line 2 + // } + public void testGNUExpressionCompoundStmtInside() { + loadCodeAndRun(getAboveComment()); + checkErrorLine(2); + } + + // main() { // int a; // +a; // error here on line 3 // } |