1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-23 14:42:11 +02:00

Bug 515464 - Fix false positive no break at the end of case

Change-Id: I0b82f4d087dd868dc2184d75abd9156986837743
This commit is contained in:
Marco Stornelli 2020-01-19 09:59:50 +01:00
parent 8dae022114
commit 2c266d91fc
2 changed files with 77 additions and 7 deletions

View file

@ -31,8 +31,10 @@ import org.eclipse.cdt.core.dom.ast.IASTComment;
import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement; import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement;
import org.eclipse.cdt.core.dom.ast.IASTContinueStatement; import org.eclipse.cdt.core.dom.ast.IASTContinueStatement;
import org.eclipse.cdt.core.dom.ast.IASTDefaultStatement; import org.eclipse.cdt.core.dom.ast.IASTDefaultStatement;
import org.eclipse.cdt.core.dom.ast.IASTDoStatement;
import org.eclipse.cdt.core.dom.ast.IASTExpressionStatement; import org.eclipse.cdt.core.dom.ast.IASTExpressionStatement;
import org.eclipse.cdt.core.dom.ast.IASTFileLocation; import org.eclipse.cdt.core.dom.ast.IASTFileLocation;
import org.eclipse.cdt.core.dom.ast.IASTForStatement;
import org.eclipse.cdt.core.dom.ast.IASTGotoStatement; import org.eclipse.cdt.core.dom.ast.IASTGotoStatement;
import org.eclipse.cdt.core.dom.ast.IASTIfStatement; import org.eclipse.cdt.core.dom.ast.IASTIfStatement;
import org.eclipse.cdt.core.dom.ast.IASTMacroExpansionLocation; import org.eclipse.cdt.core.dom.ast.IASTMacroExpansionLocation;
@ -43,6 +45,7 @@ import org.eclipse.cdt.core.dom.ast.IASTReturnStatement;
import org.eclipse.cdt.core.dom.ast.IASTStatement; import org.eclipse.cdt.core.dom.ast.IASTStatement;
import org.eclipse.cdt.core.dom.ast.IASTSwitchStatement; import org.eclipse.cdt.core.dom.ast.IASTSwitchStatement;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.IASTWhileStatement;
import org.eclipse.cdt.core.parser.StandardAttributes; import org.eclipse.cdt.core.parser.StandardAttributes;
import org.eclipse.cdt.core.parser.util.AttributeUtil; import org.eclipse.cdt.core.parser.util.AttributeUtil;
@ -80,8 +83,12 @@ public class CaseBreakChecker extends AbstractIndexAstChecker {
* - "exit" * - "exit"
*/ */
protected boolean isBreakOrExitStatement(IASTStatement statement) { protected boolean isBreakOrExitStatement(IASTStatement statement) {
return (statement instanceof IASTBreakStatement) || statement instanceof IASTReturnStatement return (statement instanceof IASTBreakStatement) || statement instanceof IASTContinueStatement
|| statement instanceof IASTContinueStatement || statement instanceof IASTGotoStatement || isExitStatement(statement);
}
protected boolean isExitStatement(IASTStatement statement) {
return statement instanceof IASTReturnStatement || statement instanceof IASTGotoStatement
|| CxxAstUtils.isThrowStatement(statement) || CxxAstUtils.isExitStatement(statement); || CxxAstUtils.isThrowStatement(statement) || CxxAstUtils.isExitStatement(statement);
} }
@ -127,7 +134,7 @@ public class CaseBreakChecker extends AbstractIndexAstChecker {
if (curr instanceof IASTNullStatement && (prev != prevCase)) { if (curr instanceof IASTNullStatement && (prev != prevCase)) {
curr = prev; curr = prev;
} }
if (!isProducedByMacroExpansion(prevCase) && isFallThroughStamement(curr)) { if (!isProducedByMacroExpansion(prevCase) && isFallThroughStamement(curr, false)) {
IASTComment comment = null; IASTComment comment = null;
if (next != null) { if (next != null) {
comment = getLeadingComment(next); comment = getLeadingComment(next);
@ -168,22 +175,34 @@ public class CaseBreakChecker extends AbstractIndexAstChecker {
* @param body * @param body
* @return * @return
*/ */
public boolean isFallThroughStamement(IASTStatement body) { public boolean isFallThroughStamement(IASTStatement body, boolean inLoop) {
if (body == null) if (body == null)
return true; return true;
if (body instanceof IASTCompoundStatement) { if (body instanceof IASTCompoundStatement) {
IASTStatement[] statements = ((IASTCompoundStatement) body).getStatements(); IASTStatement[] statements = ((IASTCompoundStatement) body).getStatements();
if (statements.length > 0) { if (statements.length > 0) {
return isFallThroughStamement(statements[statements.length - 1]); return isFallThroughStamement(statements[statements.length - 1], inLoop);
} }
return true; return true;
} else if (isBreakOrExitStatement(body)) { } else if (body instanceof IASTDoStatement) {
IASTDoStatement dos = (IASTDoStatement) body;
return isFallThroughStamement(dos.getBody(), true);
} else if (body instanceof IASTForStatement) {
IASTForStatement fors = (IASTForStatement) body;
return isFallThroughStamement(fors.getBody(), true);
} else if (body instanceof IASTWhileStatement) {
IASTWhileStatement whiles = (IASTWhileStatement) body;
return isFallThroughStamement(whiles.getBody(), true);
} else if (inLoop && isExitStatement(body)) {
return false;
} else if (!inLoop && isBreakOrExitStatement(body)) {
return false; return false;
} else if (body instanceof IASTExpressionStatement) { } else if (body instanceof IASTExpressionStatement) {
return true; return true;
} else if (body instanceof IASTIfStatement) { } else if (body instanceof IASTIfStatement) {
IASTIfStatement ifs = (IASTIfStatement) body; IASTIfStatement ifs = (IASTIfStatement) body;
return isFallThroughStamement(ifs.getThenClause()) || isFallThroughStamement(ifs.getElseClause()); return isFallThroughStamement(ifs.getThenClause(), inLoop)
|| isFallThroughStamement(ifs.getElseClause(), inLoop);
} }
return true; // TODO return true; // TODO
} }

View file

@ -809,4 +809,55 @@ public class CaseBreakCheckerTest extends CheckerTestCase {
loadCodeAndRun(getAboveComment()); loadCodeAndRun(getAboveComment());
checkErrorLines(9, 14); checkErrorLines(9, 14);
} }
//int main(int argc) {
// switch(argc)
// {
// case 12:
// for(;;) {
// throw 12;
// }
// default:
// break;
// }
// return 0;
//}
public void testWithForInCase_Bug515464() throws Exception {
loadCodeAndRun(getAboveComment());
checkNoErrorsOfKind(ER_ID);
}
//int main(int argc) {
// switch(argc)
// {
// case 12:
// while(1) {
// throw 12;
// }
// default:
// break;
// }
// return 0;
//}
public void testWithWhileInCase_Bug515464() throws Exception {
loadCodeAndRun(getAboveComment());
checkNoErrorsOfKind(ER_ID);
}
//int main(int argc) {
// switch(argc)
// {
// case 12:
// do {
// throw 12;
// } while(0);
// default:
// break;
// }
// return 0;
//}
public void testWithDoInCase_Bug515464() throws Exception {
loadCodeAndRun(getAboveComment());
checkNoErrorsOfKind(ER_ID);
}
} }