mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-29 19:45:01 +02:00
Bug 356037 - "No break at the end of case" warning for a case statement
produced by macro expansion.
This commit is contained in:
parent
82272a7965
commit
dce3efe733
3 changed files with 72 additions and 82 deletions
|
@ -52,7 +52,7 @@ problem.name.FormatString = Format String Vulnerability
|
||||||
checker.name.AssignmentToItself = Assignment to itself
|
checker.name.AssignmentToItself = Assignment to itself
|
||||||
problem.messagePattern.AssignmentToItself = Assignment to itself ''{0}''
|
problem.messagePattern.AssignmentToItself = Assignment to itself ''{0}''
|
||||||
problem.name.AssignmentToItself = Assignment to itself
|
problem.name.AssignmentToItself = Assignment to itself
|
||||||
problem.description.AssignmentToItself = Finds expression where left and right side of the assignment is the same, i.e. 'var = var'
|
problem.description.AssignmentToItself = Finds expression where left and right sides of the assignment are the same, i.e. 'var = var'
|
||||||
checker.name.ReturnStyle = Return with parenthesis
|
checker.name.ReturnStyle = Return with parenthesis
|
||||||
problem.name.ReturnStyle = Return with parenthesis
|
problem.name.ReturnStyle = Return with parenthesis
|
||||||
problem.messagePattern.ReturnStyle = Return statement has invalid style. Return value should be surrounded by parenthesis
|
problem.messagePattern.ReturnStyle = Return statement has invalid style. Return value should be surrounded by parenthesis
|
||||||
|
@ -60,10 +60,10 @@ problem.description.ReturnStyle = Checks for return statements that do no return
|
||||||
checker.name.SuspiciousSemicolon = Suspicious semicolon
|
checker.name.SuspiciousSemicolon = Suspicious semicolon
|
||||||
problem.name.SuspiciousSemicolon = Suspicious semicolon
|
problem.name.SuspiciousSemicolon = Suspicious semicolon
|
||||||
problem.messagePattern.SuspiciousSemicolon = Suspicious semicolon
|
problem.messagePattern.SuspiciousSemicolon = Suspicious semicolon
|
||||||
problem.description.SuspiciousSemicolon = A semicolon is used as a null statement in a condition. For example, 'if(expression);'
|
problem.description.SuspiciousSemicolon = A semicolon is used as a null statement in a condition. For example, 'if (expression);'
|
||||||
checker.name.CaseBreak = No break at end of case
|
checker.name.CaseBreak = No break at end of case
|
||||||
problem.description.CaseBreak = Looks for "case" statements which end without a "break" statement
|
problem.description.CaseBreak = Looks for "case" statements which end without a "break" statement
|
||||||
problem.messagePattern.CaseBreak = No break at the end of this case
|
problem.messagePattern.CaseBreak = No break at the end of case
|
||||||
binding.checker.name = Problem Binding Checker
|
binding.checker.name = Problem Binding Checker
|
||||||
problem.description.G = Name resolution problem found by the indexer
|
problem.description.G = Name resolution problem found by the indexer
|
||||||
problem.messagePattern.G = Symbol ''{0}'' could not be resolved
|
problem.messagePattern.G = Symbol ''{0}'' could not be resolved
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (c) 2010,2011 Gil Barash
|
* Copyright (c) 2010, 2011 Gil Barash
|
||||||
* All rights reserved. This program and the accompanying materials
|
* All rights reserved. This program and the accompanying materials
|
||||||
* are made available under the terms of the Eclipse Public License v1.0
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
* which accompanies this distribution, and is available at
|
* which accompanies this distribution, and is available at
|
||||||
|
@ -8,6 +8,7 @@
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* Gil Barash - Initial implementation
|
* Gil Barash - Initial implementation
|
||||||
* Elena laskavaia - Rewrote checker to reduce false positives in complex cases
|
* Elena laskavaia - Rewrote checker to reduce false positives in complex cases
|
||||||
|
* Sergey Prigogin (Google)
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.codan.internal.checkers;
|
package org.eclipse.cdt.codan.internal.checkers;
|
||||||
|
|
||||||
|
@ -50,8 +51,7 @@ public class CaseBreakChecker extends AbstractIndexAstChecker implements IChecke
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This visitor looks for "switch" statements and invokes "SwitchVisitor" on
|
* This visitor looks for "switch" statements and invokes "SwitchVisitor" on them.
|
||||||
* them.
|
|
||||||
*/
|
*/
|
||||||
class SwitchFindingVisitor extends ASTVisitor {
|
class SwitchFindingVisitor extends ASTVisitor {
|
||||||
SwitchFindingVisitor() {
|
SwitchFindingVisitor() {
|
||||||
|
@ -67,7 +67,7 @@ public class CaseBreakChecker extends AbstractIndexAstChecker implements IChecke
|
||||||
* - "continue"
|
* - "continue"
|
||||||
* - "goto" (does not check that the goto actually exists the
|
* - "goto" (does not check that the goto actually exists the
|
||||||
* switch)
|
* switch)
|
||||||
* - "thorw"
|
* - "throw"
|
||||||
* - "exit"
|
* - "exit"
|
||||||
*/
|
*/
|
||||||
protected boolean isBreakOrExitStatement(IASTStatement statement) {
|
protected boolean isBreakOrExitStatement(IASTStatement statement) {
|
||||||
|
@ -83,7 +83,7 @@ public class CaseBreakChecker extends AbstractIndexAstChecker implements IChecke
|
||||||
IASTSwitchStatement switchStmt = (IASTSwitchStatement) statement;
|
IASTSwitchStatement switchStmt = (IASTSwitchStatement) statement;
|
||||||
IASTStatement body = switchStmt.getBody();
|
IASTStatement body = switchStmt.getBody();
|
||||||
if (body instanceof IASTCompoundStatement) {
|
if (body instanceof IASTCompoundStatement) {
|
||||||
// if not it is not really a switch
|
// If not it is not really a switch
|
||||||
IASTStatement[] statements = ((IASTCompoundStatement) body).getStatements();
|
IASTStatement[] statements = ((IASTCompoundStatement) body).getStatements();
|
||||||
IASTStatement prevCase = null;
|
IASTStatement prevCase = null;
|
||||||
for (int i = 0; i < statements.length; i++) {
|
for (int i = 0; i < statements.length; i++) {
|
||||||
|
@ -97,16 +97,16 @@ public class CaseBreakChecker extends AbstractIndexAstChecker implements IChecke
|
||||||
if (isCaseStatement(curr)) {
|
if (isCaseStatement(curr)) {
|
||||||
prevCase = curr;
|
prevCase = curr;
|
||||||
}
|
}
|
||||||
// next is case or end of switch - means this one is the last
|
// Next is case or end of switch - means this one is the last
|
||||||
if (prevCase != null && (isCaseStatement(next) || next == null)) {
|
if (prevCase != null && (isCaseStatement(next) || next == null)) {
|
||||||
// check that current statement end with break or any other exit statement
|
// Check that current statement end with break or any other exit statement
|
||||||
if (!_checkEmptyCase && isCaseStatement(curr) && next != null) {
|
if (!_checkEmptyCase && isCaseStatement(curr) && next != null) {
|
||||||
continue; // empty case & we don't care
|
continue; // Empty case and we don't care
|
||||||
}
|
}
|
||||||
if (!_checkLastCase && next == null) {
|
if (!_checkLastCase && next == null) {
|
||||||
continue; // last case and we don't care
|
continue; // Last case and we don't care
|
||||||
}
|
}
|
||||||
if (isFallThroughStamement(curr)) {
|
if (!isProducedByMacroExpansion(prevCase) && isFallThroughStamement(curr)) {
|
||||||
IASTComment comment = null;
|
IASTComment comment = null;
|
||||||
if (next != null) {
|
if (next != null) {
|
||||||
comment = getLeadingComment(next);
|
comment = getLeadingComment(next);
|
||||||
|
@ -139,7 +139,7 @@ public class CaseBreakChecker extends AbstractIndexAstChecker implements IChecke
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param nextstatement
|
* @param body
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public boolean isFallThroughStamement(IASTStatement body) {
|
public boolean isFallThroughStamement(IASTStatement body) {
|
||||||
|
@ -171,13 +171,11 @@ public class CaseBreakChecker extends AbstractIndexAstChecker implements IChecke
|
||||||
IASTFileLocation astLocation = astNode.getFileLocation();
|
IASTFileLocation astLocation = astNode.getFileLocation();
|
||||||
int line = astLocation.getEndingLineNumber();
|
int line = astLocation.getEndingLineNumber();
|
||||||
IProblemLocationFactory locFactory = getRuntime().getProblemLocationFactory();
|
IProblemLocationFactory locFactory = getRuntime().getProblemLocationFactory();
|
||||||
return locFactory.createProblemLocation(getFile(), -1,
|
return locFactory.createProblemLocation(getFile(), -1, -1, line);
|
||||||
-1, line);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if the given statement is a result of macro expansion with a
|
* Checks if the given statement is a result of macro expansion with a possible
|
||||||
* possible
|
|
||||||
* exception for the trailing semicolon.
|
* exception for the trailing semicolon.
|
||||||
*
|
*
|
||||||
* @param statement the statement to check.
|
* @param statement the statement to check.
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
*
|
*
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* Gil Barash - Initial implementation
|
* Gil Barash - Initial implementation
|
||||||
|
* Sergey Prigogin (Google)
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.codan.core.internal.checkers;
|
package org.eclipse.cdt.codan.core.internal.checkers;
|
||||||
|
|
||||||
|
@ -508,8 +509,9 @@ public class CaseBreakCheckerTest extends CheckerTestCase {
|
||||||
loadCodeAndRun(code);
|
loadCodeAndRun(code);
|
||||||
checkNoErrors();
|
checkNoErrors();
|
||||||
}
|
}
|
||||||
|
|
||||||
// void foo(int a) {
|
// void foo(int a) {
|
||||||
// switch( a ) {
|
// switch(a) {
|
||||||
// case 2:
|
// case 2:
|
||||||
// if (a*2<10)
|
// if (a*2<10)
|
||||||
// return;
|
// return;
|
||||||
|
@ -525,53 +527,43 @@ public class CaseBreakCheckerTest extends CheckerTestCase {
|
||||||
checkErrorLine(7);
|
checkErrorLine(7);
|
||||||
}
|
}
|
||||||
|
|
||||||
// #define DEFINE_BREAK {break;}
|
// #define DEFINE_BREAK {break;}
|
||||||
// void foo ( int a )
|
// void foo(int a) {
|
||||||
// {
|
// switch (a) {
|
||||||
// switch ( a )
|
// case 1:
|
||||||
// {
|
// DEFINE_BREAK // No warning here
|
||||||
// case 1:
|
// }
|
||||||
// DEFINE_BREAK // <-- Warning: No break at the end of this case
|
// }
|
||||||
// }
|
|
||||||
// }
|
|
||||||
public void testBreakInBraces() {
|
public void testBreakInBraces() {
|
||||||
String code = getAboveComment();
|
String code = getAboveComment();
|
||||||
loadCodeAndRun(code);
|
loadCodeAndRun(code);
|
||||||
checkNoErrors();
|
checkNoErrors();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// #define MY_MACRO(i) \
|
||||||
// #define MY_MACRO(i) \
|
// case i: { \
|
||||||
// case i: \
|
// }
|
||||||
// { \
|
//
|
||||||
// break; \
|
// void f() {
|
||||||
// }
|
// int x;
|
||||||
//
|
// switch (x) {
|
||||||
// void f()
|
// MY_MACRO(1) // No warning here
|
||||||
// {
|
// }
|
||||||
// int x;
|
// }
|
||||||
// switch (x)
|
|
||||||
// {
|
|
||||||
// MY_MACRO(1) // WARNING HERE
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
public void testInMacro() {
|
public void testInMacro() {
|
||||||
String code = getAboveComment();
|
String code = getAboveComment();
|
||||||
loadCodeAndRun(code);
|
loadCodeAndRun(code);
|
||||||
checkNoErrors();
|
checkNoErrors();
|
||||||
}
|
}
|
||||||
|
|
||||||
//void foo()
|
// void foo() {
|
||||||
//{
|
// switch (0)
|
||||||
//switch(0)
|
// default: {
|
||||||
//default:
|
// }
|
||||||
//{
|
// }
|
||||||
//}
|
|
||||||
//}
|
|
||||||
public void testEmptyCompoundStatement() {
|
public void testEmptyCompoundStatement() {
|
||||||
String code = getAboveComment();
|
String code = getAboveComment();
|
||||||
loadCodeAndRun(code);
|
loadCodeAndRun(code);
|
||||||
checkErrorLine(6);
|
checkErrorLine(4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue