1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-06-07 01:36:01 +02:00

cleanup up some login in return checker and optimized (not building cfg for simple cases)

This commit is contained in:
Alena Laskavaia 2011-05-01 23:14:04 +00:00
parent a63a62bc4f
commit 55b32bcd97

View file

@ -81,18 +81,20 @@ public class ReturnChecker extends AbstractAstFunctionChecker {
return PROCESS_SKIP; // skip inner functions return PROCESS_SKIP; // skip inner functions
return PROCESS_CONTINUE; return PROCESS_CONTINUE;
} }
public int visit(IASTExpression expr) { public int visit(IASTExpression expr) {
if (expr instanceof ICPPASTLambdaExpression) { if (expr instanceof ICPPASTLambdaExpression) {
return PROCESS_SKIP; return PROCESS_SKIP;
} }
return PROCESS_CONTINUE; return PROCESS_CONTINUE;
} }
public int visit(IASTStatement stmt) { public int visit(IASTStatement stmt) {
if (stmt instanceof IASTReturnStatement) { if (stmt instanceof IASTReturnStatement) {
IASTReturnStatement ret = (IASTReturnStatement) stmt; IASTReturnStatement ret = (IASTReturnStatement) stmt;
boolean hasValue = ret.getReturnValue() != null; boolean hasValue = ret.getReturnValue() != null;
if (hasret==false && hasValue) { if (hasret == false && hasValue) {
hasret=true; hasret = true;
} }
if (!isVoid(func) && !isConstructorDestructor()) { if (!isVoid(func) && !isConstructorDestructor()) {
if (checkImplicitReturn(RET_NO_VALUE_ID) || isExplicitReturn(func)) { if (checkImplicitReturn(RET_NO_VALUE_ID) || isExplicitReturn(func)) {
@ -141,30 +143,39 @@ public class ReturnChecker extends AbstractAstFunctionChecker {
func.accept(visitor); func.accept(visitor);
boolean nonVoid = !isVoid(func); boolean nonVoid = !isVoid(func);
if (nonVoid) { if (nonVoid) {
if (!visitor.hasret) { // there a return but maybe it is only on one branch
// no return at all IASTStatement body = func.getBody();
if (checkImplicitReturn(RET_NORET_ID) || isExplicitReturn(func)) { if (body instanceof IASTCompoundStatement) {
if (endsWithNoExitNode(func)) IASTStatement[] statements = ((IASTCompoundStatement) body).getStatements();
reportProblem(RET_NORET_ID, func.getDeclSpecifier()); if (statements.length > 0) {
} IASTStatement last = statements[statements.length - 1];
} else { // now check if last statement if complex (for optimization reasons, building CFG is expensive)
// there a return but maybe it is only on one branch if (isCompoundStatement(last)) {
IASTStatement body = func.getBody(); if (endsWithNoExitNode(func))
if (body instanceof IASTCompoundStatement) { reportNoRet(func, visitor.hasret);
IASTStatement[] statements = ((IASTCompoundStatement) body).getStatements(); } else if (!isFuncExitStatement(last)) {
if (statements.length > 0) { reportNoRet(func, visitor.hasret);
IASTStatement last = statements[statements.length - 1];
// now check if last statement if complex (for optimization reasons, building CFG is expensive)
if (isCompoundStatement(last)) {
if (endsWithNoExitNode(func))
reportProblem(RET_NORET_ID, func.getDeclSpecifier());
}
} }
} else {
reportNoRet(func, false);
} }
} }
} }
} }
/**
* @param func
*/
protected void reportNoRet(IASTFunctionDefinition func, boolean hasRet) {
if (!hasRet) {
// no return at all
if (checkImplicitReturn(RET_NORET_ID) == false && isExplicitReturn(func) == false) {
return;
}
}
reportProblem(RET_NORET_ID, func.getDeclSpecifier());
}
/** /**
* @param last * @param last
* @return * @return
@ -174,6 +185,11 @@ public class ReturnChecker extends AbstractAstFunctionChecker {
|| last instanceof IASTForStatement || last instanceof IASTSwitchStatement; || last instanceof IASTForStatement || last instanceof IASTSwitchStatement;
} }
protected boolean isFuncExitStatement(IASTStatement statement) {
CxxAstUtils utils = CxxAstUtils.getInstance();
return statement instanceof IASTReturnStatement || utils.isThrowStatement(statement) || utils.isExitStatement(statement);
}
/** /**
* @param if - problem id * @param if - problem id
* @return true if need to check inside functions with implicit return * @return true if need to check inside functions with implicit return
@ -275,39 +291,39 @@ public class ReturnChecker extends AbstractAstFunctionChecker {
addPreference(problem, PARAM_IMPLICIT, CheckersMessages.ReturnChecker_Param0, Boolean.FALSE); addPreference(problem, PARAM_IMPLICIT, CheckersMessages.ReturnChecker_Param0, Boolean.FALSE);
} }
} }
/** /**
* Checks if a "void" return type is specified using the C++0x late-specified return type * Checks if a "void" return type is specified using the C++0x
* late-specified return type
* for a given function definition * for a given function definition
* *
* For example, auto f() -> void { } would return true * For example, auto f() -> void { } would return true
* *
* @param functionDefinition * @param functionDefinition
* @return True if the function has a void (late-specified) return type, False otherwise * @return True if the function has a void (late-specified) return type,
* False otherwise
*/ */
private boolean isAutoVoid(IASTFunctionDefinition functionDefinition) { private boolean isAutoVoid(IASTFunctionDefinition functionDefinition) {
IASTFunctionDeclarator declarator = functionDefinition.getDeclarator(); IASTFunctionDeclarator declarator = functionDefinition.getDeclarator();
if(declarator instanceof ICPPASTFunctionDeclarator) { if (declarator instanceof ICPPASTFunctionDeclarator) {
ICPPASTFunctionDeclarator functionDeclarator = (ICPPASTFunctionDeclarator) declarator; ICPPASTFunctionDeclarator functionDeclarator = (ICPPASTFunctionDeclarator) declarator;
IASTTypeId trailingReturnType = functionDeclarator.getTrailingReturnType(); IASTTypeId trailingReturnType = functionDeclarator.getTrailingReturnType();
if(trailingReturnType != null) { if (trailingReturnType != null) {
IASTDeclarator abstractDeclarator = trailingReturnType.getAbstractDeclarator(); IASTDeclarator abstractDeclarator = trailingReturnType.getAbstractDeclarator();
if(abstractDeclarator != null) { if (abstractDeclarator != null) {
if(abstractDeclarator.getPointerOperators().length > 0) { if (abstractDeclarator.getPointerOperators().length > 0) {
return false; return false;
} }
IASTDeclSpecifier declSpecifier = trailingReturnType.getDeclSpecifier(); IASTDeclSpecifier declSpecifier = trailingReturnType.getDeclSpecifier();
if(declSpecifier instanceof ICPPASTSimpleDeclSpecifier) { if (declSpecifier instanceof ICPPASTSimpleDeclSpecifier) {
ICPPASTSimpleDeclSpecifier simpleDeclSpecifier = (ICPPASTSimpleDeclSpecifier) declSpecifier; ICPPASTSimpleDeclSpecifier simpleDeclSpecifier = (ICPPASTSimpleDeclSpecifier) declSpecifier;
if(simpleDeclSpecifier.getType() == IASTSimpleDeclSpecifier.t_void) { if (simpleDeclSpecifier.getType() == IASTSimpleDeclSpecifier.t_void) {
return true; return true;
} }
} }
} }
} }
} }
return false;
return false; }
}
} }