mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-06-07 01:36:01 +02:00
Added parameters for checker - to check for implict return
This commit is contained in:
parent
4e0a4b9171
commit
e6499a96f6
1 changed files with 34 additions and 5 deletions
|
@ -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.AbstractAstFunctionChecker;
|
||||||
import org.eclipse.cdt.codan.core.cxx.model.CxxModelsCache;
|
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.ICfgData;
|
||||||
import org.eclipse.cdt.codan.core.model.cfg.IControlFlowGraph;
|
import org.eclipse.cdt.codan.core.model.cfg.IControlFlowGraph;
|
||||||
import org.eclipse.cdt.codan.core.model.cfg.IExitNode;
|
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.ASTVisitor;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
|
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator;
|
import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator;
|
||||||
|
@ -34,7 +40,9 @@ import org.eclipse.cdt.core.dom.ast.c.ICASTSimpleDeclSpecifier;
|
||||||
* <li>Function declared as returning non-void has no return (requires control
|
* <li>Function declared as returning non-void has no return (requires control
|
||||||
* flow graph)
|
* 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_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_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$
|
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) {
|
if (stmt instanceof IASTReturnStatement) {
|
||||||
IASTReturnStatement ret = (IASTReturnStatement) stmt;
|
IASTReturnStatement ret = (IASTReturnStatement) stmt;
|
||||||
if (!isVoid(func)) {
|
if (!isVoid(func)) {
|
||||||
if (isExplicitReturn(func)) {
|
if (checkImplicitReturn(RET_NO_VALUE_ID) ||isExplicitReturn(func)) {
|
||||||
if (ret.getReturnValue() == null)
|
if (ret.getReturnValue() == null)
|
||||||
reportProblem(RET_NO_VALUE_ID, ret);
|
reportProblem(RET_NO_VALUE_ID, ret);
|
||||||
}
|
}
|
||||||
|
@ -80,13 +88,23 @@ public class ReturnChecker extends AbstractAstFunctionChecker {
|
||||||
func.accept(visitor);
|
func.accept(visitor);
|
||||||
if (!visitor.hasret) {
|
if (!visitor.hasret) {
|
||||||
// no return at all
|
// no return at all
|
||||||
if (!isVoid(func) && isExplicitReturn(func)) {
|
if (!isVoid(func)
|
||||||
|
&& (checkImplicitReturn(RET_NORET_ID) || isExplicitReturn(func))) {
|
||||||
if (endsWithNoExitNode(func))
|
if (endsWithNoExitNode(func))
|
||||||
reportProblem(RET_NORET_ID, func.getDeclSpecifier());
|
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
|
* @param func
|
||||||
* @return
|
* @return
|
||||||
|
@ -94,8 +112,7 @@ public class ReturnChecker extends AbstractAstFunctionChecker {
|
||||||
protected boolean endsWithNoExitNode(IASTFunctionDefinition func) {
|
protected boolean endsWithNoExitNode(IASTFunctionDefinition func) {
|
||||||
IControlFlowGraph graph = CxxModelsCache.getInstance()
|
IControlFlowGraph graph = CxxModelsCache.getInstance()
|
||||||
.getControlFlowGraph(func);
|
.getControlFlowGraph(func);
|
||||||
Iterator<IExitNode> exitNodeIterator = graph
|
Iterator<IExitNode> exitNodeIterator = graph.getExitNodeIterator();
|
||||||
.getExitNodeIterator();
|
|
||||||
boolean noexitop = false;
|
boolean noexitop = false;
|
||||||
for (; exitNodeIterator.hasNext();) {
|
for (; exitNodeIterator.hasNext();) {
|
||||||
IExitNode node = exitNodeIterator.next();
|
IExitNode node = exitNodeIterator.next();
|
||||||
|
@ -144,4 +161,16 @@ public class ReturnChecker extends AbstractAstFunctionChecker {
|
||||||
}
|
}
|
||||||
return type;
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue