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:
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.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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue