diff --git a/codan/org.eclipse.cdt.codan.checkers/src/org/eclipse/cdt/codan/internal/checkers/SuspiciousSemicolonChecker.java b/codan/org.eclipse.cdt.codan.checkers/src/org/eclipse/cdt/codan/internal/checkers/SuspiciousSemicolonChecker.java index dce5cee2077..e194ab1dc92 100644 --- a/codan/org.eclipse.cdt.codan.checkers/src/org/eclipse/cdt/codan/internal/checkers/SuspiciousSemicolonChecker.java +++ b/codan/org.eclipse.cdt.codan.checkers/src/org/eclipse/cdt/codan/internal/checkers/SuspiciousSemicolonChecker.java @@ -1,12 +1,13 @@ /******************************************************************************* - * Copyright (c) 2010 Marc-Andre Laperle and others. + * Copyright (c) 2010, 2011 Marc-Andre Laperle and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * Marc-Andre Laperle - Initial API and implementation + * Marc-Andre Laperle - Initial API and implementation + * Sergey Prigogin (Google) *******************************************************************************/ package org.eclipse.cdt.codan.internal.checkers; @@ -38,15 +39,15 @@ public class SuspiciousSemicolonChecker extends AbstractIndexAstChecker { if (statement instanceof IASTIfStatement) { IASTStatement thenStmt = ((IASTIfStatement) statement).getThenClause(); IASTStatement elseStmt = ((IASTIfStatement) statement).getElseClause(); - if (elseStmt instanceof IASTNullStatement && noMacroInvolved(elseStmt) && doReportAfterElse()) { + if (elseStmt instanceof IASTNullStatement && doReportAfterElse() && + !macroInvolved(elseStmt)) { reportProblem(ER_ID, elseStmt); } - if (elseStmt != null && doNotReportIfElse() == true) + if (elseStmt != null && doNotReportIfElse()) return PROCESS_CONTINUE; - if (thenStmt instanceof IASTNullStatement && noMacroInvolved(thenStmt)) { + if (thenStmt instanceof IASTNullStatement && !macroInvolved(thenStmt)) { reportProblem(ER_ID, thenStmt); } - } return PROCESS_CONTINUE; } @@ -57,16 +58,20 @@ public class SuspiciousSemicolonChecker extends AbstractIndexAstChecker { final IProblem pt = getProblemById(ER_ID, getFile()); return (Boolean) getPreference(pt, PARAM_ELSE); } + protected boolean doReportAfterElse() { final IProblem pt = getProblemById(ER_ID, getFile()); return (Boolean) getPreference(pt, PARAM_ALFTER_ELSE); } - protected boolean noMacroInvolved(IASTStatement node) { + protected boolean macroInvolved(IASTStatement node) { + if (includesMacroExpansion(node)) { + return true; + } IASTNodeSelector nodeSelector = node.getTranslationUnit().getNodeSelector(node.getTranslationUnit().getFilePath()); IASTFileLocation fileLocation = node.getFileLocation(); IASTPreprocessorMacroExpansion macro = nodeSelector.findEnclosingMacroExpansion(fileLocation.getNodeOffset() - 1, 1); - return macro == null; + return macro != null; } public void initPreferences(IProblemWorkingCopy problem) { diff --git a/codan/org.eclipse.cdt.codan.core.cxx/src/org/eclipse/cdt/codan/core/cxx/model/AbstractIndexAstChecker.java b/codan/org.eclipse.cdt.codan.core.cxx/src/org/eclipse/cdt/codan/core/cxx/model/AbstractIndexAstChecker.java index 2a99930285b..fa9a7e059b7 100644 --- a/codan/org.eclipse.cdt.codan.core.cxx/src/org/eclipse/cdt/codan/core/cxx/model/AbstractIndexAstChecker.java +++ b/codan/org.eclipse.cdt.codan.core.cxx/src/org/eclipse/cdt/codan/core/cxx/model/AbstractIndexAstChecker.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2009, 2010 Alena Laskavaia + * Copyright (c) 2009, 2011 Alena Laskavaia * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -23,6 +23,7 @@ import org.eclipse.cdt.core.dom.ast.IASTImageLocation; import org.eclipse.cdt.core.dom.ast.IASTMacroExpansionLocation; import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTNode; +import org.eclipse.cdt.core.dom.ast.IASTNodeLocation; import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; import org.eclipse.cdt.core.model.CoreModel; import org.eclipse.cdt.core.model.ICElement; @@ -132,7 +133,7 @@ public abstract class AbstractIndexAstChecker extends AbstractCheckerWithProblem private IProblemLocation getProblemLocation(IASTNode astNode, IASTFileLocation astLocation) { int line = astLocation.getStartingLineNumber(); IProblemLocationFactory locFactory = getRuntime().getProblemLocationFactory(); - if (hasMacroLocation(astNode) && astNode instanceof IASTName) { + if (enclosedInMacroExpansion(astNode) && astNode instanceof IASTName) { IASTImageLocation imageLocation = ((IASTName) astNode).getImageLocation(); if (imageLocation != null) { int start = imageLocation.getNodeOffset(); @@ -147,9 +148,17 @@ public abstract class AbstractIndexAstChecker extends AbstractCheckerWithProblem return locFactory.createProblemLocation(getFile(), line); } - private boolean hasMacroLocation(IASTNode astNode) { - return astNode.getNodeLocations().length == 1 && - astNode.getNodeLocations()[0] instanceof IASTMacroExpansionLocation; + protected static boolean enclosedInMacroExpansion(IASTNode node) { + IASTNodeLocation[] nodeLocations = node.getNodeLocations(); + return nodeLocations.length == 1 && nodeLocations[0] instanceof IASTMacroExpansionLocation; + } + + protected static boolean includesMacroExpansion(IASTNode node) { + for (IASTNodeLocation nodeLocation : node.getNodeLocations()) { + if (nodeLocation instanceof IASTMacroExpansionLocation) + return true; + } + return false; } protected IFile getFile() { diff --git a/codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/internal/checkers/SuspiciousSemicolonCheckerTest.java b/codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/internal/checkers/SuspiciousSemicolonCheckerTest.java index 2b4d1d39e94..cf4f4f1530d 100644 --- a/codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/internal/checkers/SuspiciousSemicolonCheckerTest.java +++ b/codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/internal/checkers/SuspiciousSemicolonCheckerTest.java @@ -144,14 +144,23 @@ public class SuspiciousSemicolonCheckerTest extends CheckerTestCase { // #define OP // void foo() { - // if(0) - // OP; + // if(0) + // OP; // } public void testMacro() { loadCodeAndRun(getAboveComment()); checkNoErrors(); } + // #define MACRO(cond) if (cond) ; + // void foo() { + // MACRO(true); + // } + public void testMacroExpansion() { + loadCodeAndRun(getAboveComment()); + checkNoErrors(); + } + // main() { // if (false) // ; // only this one is reported