diff --git a/codan/org.eclipse.cdt.codan.checkers/src/org/eclipse/cdt/codan/internal/checkers/ReturnChecker.java b/codan/org.eclipse.cdt.codan.checkers/src/org/eclipse/cdt/codan/internal/checkers/ReturnChecker.java index ec25fc7c8f5..f2c098eb037 100644 --- a/codan/org.eclipse.cdt.codan.checkers/src/org/eclipse/cdt/codan/internal/checkers/ReturnChecker.java +++ b/codan/org.eclipse.cdt.codan.checkers/src/org/eclipse/cdt/codan/internal/checkers/ReturnChecker.java @@ -14,9 +14,15 @@ import java.util.Iterator; import org.eclipse.cdt.codan.core.cxx.model.AbstractAstFunctionChecker; import org.eclipse.cdt.codan.core.cxx.model.CxxModelsCache; +import org.eclipse.cdt.codan.core.model.ICheckerWithParameters; +import org.eclipse.cdt.codan.core.model.IProblem; +import org.eclipse.cdt.codan.core.model.IProblemWorkingCopy; import org.eclipse.cdt.codan.core.model.cfg.ICfgData; import org.eclipse.cdt.codan.core.model.cfg.IControlFlowGraph; import org.eclipse.cdt.codan.core.model.cfg.IExitNode; +import org.eclipse.cdt.codan.core.param.HashParameterInfo; +import org.eclipse.cdt.codan.core.param.IProblemParameterInfo.ParameterType; +import org.eclipse.cdt.codan.core.param.SingleParameterInfo; import org.eclipse.cdt.core.dom.ast.ASTVisitor; import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier; import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator; @@ -34,7 +40,9 @@ import org.eclipse.cdt.core.dom.ast.c.ICASTSimpleDeclSpecifier; *
  • Function declared as returning non-void has no return (requires control * flow graph) */ -public class ReturnChecker extends AbstractAstFunctionChecker { +public class ReturnChecker extends AbstractAstFunctionChecker implements + ICheckerWithParameters { + private static final String PARAM_IMPLICIT = "implicit"; //$NON-NLS-1$ public final String RET_NO_VALUE_ID = "org.eclipse.cdt.codan.checkers.noreturn"; //$NON-NLS-1$ public final String RET_ERR_VALUE_ID = "org.eclipse.cdt.codan.checkers.errreturnvalue"; //$NON-NLS-1$ public final String RET_NORET_ID = "org.eclipse.cdt.codan.checkers.errnoreturn"; //$NON-NLS-1$ @@ -53,7 +61,7 @@ public class ReturnChecker extends AbstractAstFunctionChecker { if (stmt instanceof IASTReturnStatement) { IASTReturnStatement ret = (IASTReturnStatement) stmt; if (!isVoid(func)) { - if (isExplicitReturn(func)) { + if (checkImplicitReturn(RET_NO_VALUE_ID) ||isExplicitReturn(func)) { if (ret.getReturnValue() == null) reportProblem(RET_NO_VALUE_ID, ret); } @@ -80,13 +88,23 @@ public class ReturnChecker extends AbstractAstFunctionChecker { func.accept(visitor); if (!visitor.hasret) { // no return at all - if (!isVoid(func) && isExplicitReturn(func)) { + if (!isVoid(func) + && (checkImplicitReturn(RET_NORET_ID) || isExplicitReturn(func))) { if (endsWithNoExitNode(func)) reportProblem(RET_NORET_ID, func.getDeclSpecifier()); } } } + /** + * @param if - problem id + * @return true if need to check inside functions with implicit return + */ + protected boolean checkImplicitReturn(String id) { + final IProblem pt = getProblemById(id, getFile()); + return (Boolean) pt.getParameter(PARAM_IMPLICIT); + } + /** * @param func * @return @@ -94,8 +112,7 @@ public class ReturnChecker extends AbstractAstFunctionChecker { protected boolean endsWithNoExitNode(IASTFunctionDefinition func) { IControlFlowGraph graph = CxxModelsCache.getInstance() .getControlFlowGraph(func); - Iterator exitNodeIterator = graph - .getExitNodeIterator(); + Iterator exitNodeIterator = graph.getExitNodeIterator(); boolean noexitop = false; for (; exitNodeIterator.hasNext();) { IExitNode node = exitNodeIterator.next(); @@ -144,4 +161,16 @@ public class ReturnChecker extends AbstractAstFunctionChecker { } return type; } + + /* checker must implement @link ICheckerWithParameters */ + public void initParameters(IProblemWorkingCopy problem) { + if (problem.getId().equals(RET_NO_VALUE_ID) + || problem.getId().equals(RET_NORET_ID)) { + HashParameterInfo info1 = new HashParameterInfo(); + info1.setElement(new SingleParameterInfo(PARAM_IMPLICIT, + CheckersMessages.ReturnChecker_Param0, ParameterType.TYPE_BOOLEAN)); + problem.setParameterInfo(info1); + problem.setParameter(PARAM_IMPLICIT, Boolean.FALSE); + } + } }