mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-23 06:32:10 +02:00
Bug 515464 - Fix false positive no break at the end of case
Change-Id: I0b82f4d087dd868dc2184d75abd9156986837743
This commit is contained in:
parent
8dae022114
commit
2c266d91fc
2 changed files with 77 additions and 7 deletions
|
@ -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.IASTContinueStatement;
|
||||
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.IASTFileLocation;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTForStatement;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTGotoStatement;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTIfStatement;
|
||||
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.IASTSwitchStatement;
|
||||
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.util.AttributeUtil;
|
||||
|
||||
|
@ -80,8 +83,12 @@ public class CaseBreakChecker extends AbstractIndexAstChecker {
|
|||
* - "exit"
|
||||
*/
|
||||
protected boolean isBreakOrExitStatement(IASTStatement statement) {
|
||||
return (statement instanceof IASTBreakStatement) || statement instanceof IASTReturnStatement
|
||||
|| statement instanceof IASTContinueStatement || statement instanceof IASTGotoStatement
|
||||
return (statement instanceof IASTBreakStatement) || statement instanceof IASTContinueStatement
|
||||
|| isExitStatement(statement);
|
||||
}
|
||||
|
||||
protected boolean isExitStatement(IASTStatement statement) {
|
||||
return statement instanceof IASTReturnStatement || statement instanceof IASTGotoStatement
|
||||
|| CxxAstUtils.isThrowStatement(statement) || CxxAstUtils.isExitStatement(statement);
|
||||
}
|
||||
|
||||
|
@ -127,7 +134,7 @@ public class CaseBreakChecker extends AbstractIndexAstChecker {
|
|||
if (curr instanceof IASTNullStatement && (prev != prevCase)) {
|
||||
curr = prev;
|
||||
}
|
||||
if (!isProducedByMacroExpansion(prevCase) && isFallThroughStamement(curr)) {
|
||||
if (!isProducedByMacroExpansion(prevCase) && isFallThroughStamement(curr, false)) {
|
||||
IASTComment comment = null;
|
||||
if (next != null) {
|
||||
comment = getLeadingComment(next);
|
||||
|
@ -168,22 +175,34 @@ public class CaseBreakChecker extends AbstractIndexAstChecker {
|
|||
* @param body
|
||||
* @return
|
||||
*/
|
||||
public boolean isFallThroughStamement(IASTStatement body) {
|
||||
public boolean isFallThroughStamement(IASTStatement body, boolean inLoop) {
|
||||
if (body == null)
|
||||
return true;
|
||||
if (body instanceof IASTCompoundStatement) {
|
||||
IASTStatement[] statements = ((IASTCompoundStatement) body).getStatements();
|
||||
if (statements.length > 0) {
|
||||
return isFallThroughStamement(statements[statements.length - 1]);
|
||||
return isFallThroughStamement(statements[statements.length - 1], inLoop);
|
||||
}
|
||||
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;
|
||||
} else if (body instanceof IASTExpressionStatement) {
|
||||
return true;
|
||||
} else if (body instanceof IASTIfStatement) {
|
||||
IASTIfStatement ifs = (IASTIfStatement) body;
|
||||
return isFallThroughStamement(ifs.getThenClause()) || isFallThroughStamement(ifs.getElseClause());
|
||||
return isFallThroughStamement(ifs.getThenClause(), inLoop)
|
||||
|| isFallThroughStamement(ifs.getElseClause(), inLoop);
|
||||
}
|
||||
return true; // TODO
|
||||
}
|
||||
|
|
|
@ -809,4 +809,55 @@ public class CaseBreakCheckerTest extends CheckerTestCase {
|
|||
loadCodeAndRun(getAboveComment());
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue