From 70c9a7b64206bf483d3f7ebcf1cbedd9770edc39 Mon Sep 17 00:00:00 2001 From: Nathan Ridge Date: Sun, 14 Jul 2013 02:24:22 -0400 Subject: Bug 399146 - Bogus 'statement has no effect' warning for call to overloaded operator Change-Id: Ie2092903356e048d96b8507ce30ec2d3edc2b2f7 Signed-off-by: Nathan Ridge Reviewed-on: https://git.eclipse.org/r/14534 Reviewed-by: Sergey Prigogin IP-Clean: Sergey Prigogin Tested-by: Sergey Prigogin --- .../checkers/StatementHasNoEffectChecker.java | 34 +++++++++++++++++----- .../checkers/StatementHasNoEffectCheckerTest.java | 13 +++++++++ 2 files changed, 40 insertions(+), 7 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 3b7c1ace670..c3f140e51ab 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 @@ -82,6 +82,8 @@ public class StatementHasNoEffectChecker extends AbstractIndexAstChecker { IASTBinaryExpression binExpr = (IASTBinaryExpression) e; if (isPossibleAssignment(binExpr)) return false; + if (usesOverloadedOperator(binExpr)) + return false; switch (binExpr.getOperator()) { case IASTBinaryExpression.op_logicalOr: case IASTBinaryExpression.op_logicalAnd: @@ -91,6 +93,8 @@ public class StatementHasNoEffectChecker extends AbstractIndexAstChecker { } if (e instanceof IASTUnaryExpression) { IASTUnaryExpression unaryExpr = (IASTUnaryExpression) e; + if (usesOverloadedOperator(unaryExpr)) + return false; int operator = unaryExpr.getOperator(); switch (operator) { case IASTUnaryExpression.op_postFixDecr: @@ -131,14 +135,14 @@ public class StatementHasNoEffectChecker extends AbstractIndexAstChecker { CheckersMessages.GenericParameter_ParameterExceptionsItem); } - public boolean isFilteredArg(String arg) { + private boolean isFilteredArg(String arg) { return isFilteredArg(arg, getProblemById(ER_ID, getFile()), PARAM_EXCEPT_ARG_LIST); } /** * @return */ - public boolean shouldReportInMacro() { + private boolean shouldReportInMacro() { return (Boolean) getPreference(getProblemById(ER_ID, getFile()), PARAM_MACRO_ID); } @@ -157,15 +161,31 @@ public class StatementHasNoEffectChecker extends AbstractIndexAstChecker { case IASTBinaryExpression.op_shiftRightAssign: return true; } + return false; + } + + private boolean usesOverloadedOperator(IASTBinaryExpression expr) { + if (expr instanceof IASTImplicitNameOwner) { + IASTImplicitName[] implicitNames = ((IASTImplicitNameOwner) expr).getImplicitNames(); + if (implicitNames.length > 0) + return true; + IType operand1Type = expr.getOperand1().getExpressionType(); + IType operand2Type = expr.getOperand2().getExpressionType(); + if (!(operand1Type instanceof IBasicType && operand2Type instanceof IBasicType)) { + return true; // must be overloaded but parser could not find it + } + } + return false; + } + + private boolean usesOverloadedOperator(IASTUnaryExpression expr) { if (expr instanceof IASTImplicitNameOwner) { - // Check whether the operator is overloaded IASTImplicitName[] implicitNames = ((IASTImplicitNameOwner) expr).getImplicitNames(); if (implicitNames.length > 0) return true; - IType expressionType = expr.getOperand1().getExpressionType(); - if (!(expressionType instanceof IBasicType)) { - return true; // must be overloaded but parser could not - // find it + IType operandType = expr.getOperand().getExpressionType(); + if (!(operandType instanceof IBasicType)) { + return true; // must be overloaded but parser could not find it } } 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 53b7b037077..80481aae626 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 @@ -187,4 +187,17 @@ public class StatementHasNoEffectCheckerTest extends CheckerTestCase { IMarker m = checkErrorLine(3); assertMessageMatch("'\\+a'", m); //$NON-NLS-1$ } + + // class S { + // int operator*(); // may have side effect + // }; + // + // int main() { + // S s; + // *s; + // } + public void testOverloadedOperator_bug399146() { + loadCodeAndRunCpp(getAboveComment()); + checkNoErrors(); + } } -- cgit v1.2.3