diff options
author | Elliott Baron <ebaron@fedoraproject.org> | 2009-11-08 21:01:52 -0500 |
---|---|---|
committer | Elliott Baron <ebaron@fedoraproject.org> | 2009-11-08 21:01:52 -0500 |
commit | 4e991b89471d65f4f02e1ad54f2b85759ad80586 (patch) | |
tree | 6fc90e471e6cdeb5a22af7117e65f5bf6c6ea9fa /org.eclipse.cdt.codan.extension | |
parent | 07719f845f1e6045ed5c1553eafa9c632e53e8bf (diff) | |
download | codan-4e991b89471d65f4f02e1ad54f2b85759ad80586.tar.gz codan-4e991b89471d65f4f02e1ad54f2b85759ad80586.tar.xz codan-4e991b89471d65f4f02e1ad54f2b85759ad80586.zip |
Added fopen/fclose checker. Created abstract open/close checker.
* org.eclipse.cdt.codan.extension/plugin.xml: Added fopen/fclose checker.
* org.eclipse.cdt.codan.extension/src/org/eclipse/cdt/codan/extension/checkers/AbstractOpenCloseChecker.java: New file.
* org.eclipse.cdt.codan.extension/src/org/eclipse/cdt/codan/extension/checkers/CloseOpenedFilesChecker.java: Abstracted most code.
* org.eclipse.cdt.codan.extension/src/org/eclipse/cdt/codan/extension/checkers/FOpenFCloseChecker.java: New file.
* org.eclipse.cdt.codan.extension/src/org/eclipse/cdt/codan/extension/checkers/FunctionNameParser.java: Pass normalize = false to ASTTypeUtil.getType().
Diffstat (limited to 'org.eclipse.cdt.codan.extension')
5 files changed, 222 insertions, 137 deletions
diff --git a/org.eclipse.cdt.codan.extension/plugin.xml b/org.eclipse.cdt.codan.extension/plugin.xml index 829c8fd..5fd3060 100644 --- a/org.eclipse.cdt.codan.extension/plugin.xml +++ b/org.eclipse.cdt.codan.extension/plugin.xml @@ -5,13 +5,24 @@ point="org.eclipse.cdt.codan.core.checkers"> <checker class="org.eclipse.cdt.codan.extension.checkers.CloseOpenedFilesChecker" - id="org.eclipse.cdt.codan.extension.CloseOpenedFilesChecker" - name="Closing unopened file"> + id="org.eclipse.cdt.codan.extension.checkers.CloseOpenedFilesChecker" + name="Improper use of open/close"> <problem category="org.eclipse.cdt.codan.core.categories.ProgrammingProblems" defaultSeverity="Warning" - id="org.eclipse.cdt.codan.extension.CloseOpenedFilesProblem" - name="Attempting to close an unopened file"> + id="org.eclipse.cdt.codan.extension.OpenCloseFilesProblem" + name="Improper use of open/close"> + </problem> + </checker> + <checker + class="org.eclipse.cdt.codan.extension.checkers.FOpenFCloseChecker" + id="org.eclipse.cdt.codan.extension.checkers.FOpenFCloseChecker" + name="Improper use of fopen/fclose"> + <problem + category="org.eclipse.cdt.codan.core.categories.ProgrammingProblems" + defaultSeverity="Warning" + id="org.eclipse.cdt.codan.extension.FOpenFCloseFilesProblem" + name="Improper use of fopen/fclose"> </problem> </checker> </extension> diff --git a/org.eclipse.cdt.codan.extension/src/org/eclipse/cdt/codan/extension/checkers/AbstractOpenCloseChecker.java b/org.eclipse.cdt.codan.extension/src/org/eclipse/cdt/codan/extension/checkers/AbstractOpenCloseChecker.java new file mode 100644 index 0000000..f457364 --- /dev/null +++ b/org.eclipse.cdt.codan.extension/src/org/eclipse/cdt/codan/extension/checkers/AbstractOpenCloseChecker.java @@ -0,0 +1,151 @@ +/******************************************************************************* + * Copyright (c) 2009 Elliott Baron + * 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: + * Elliott Baron - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.codan.extension.checkers; + +import java.io.File; +import java.net.URI; +import java.util.HashSet; +import java.util.Set; + +import org.eclipse.cdt.codan.core.model.AbstractIndexAstChecker; +import org.eclipse.cdt.codan.extension.ExecutionState; +import org.eclipse.cdt.codan.extension.IPropertyFSM; +import org.eclipse.cdt.codan.extension.PropertySimulator; +import org.eclipse.cdt.codan.extension.PropertyState; +import org.eclipse.cdt.codan.extension.SymbolicState; +import org.eclipse.cdt.core.dom.ast.IASTNode; +import org.eclipse.cdt.core.dom.ast.IASTStatement; +import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IWorkspaceRoot; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.ptp.pldt.mpi.analysis.cdt.graphs.GraphCreator; +import org.eclipse.ptp.pldt.mpi.analysis.cdt.graphs.ICallGraph; +import org.eclipse.ptp.pldt.mpi.analysis.cdt.graphs.ICallGraphNode; +import org.eclipse.ptp.pldt.mpi.analysis.cdt.graphs.IControlFlowGraph; +import org.eclipse.ptp.pldt.mpi.analysis.cdt.graphs.impl.ControlFlowGraph; + +public abstract class AbstractOpenCloseChecker extends AbstractIndexAstChecker { + private IPropertyFSM fsm; + + // Property FSM states + private PropertyState uninit; + private PropertyState error; + private PropertyState opened; + + public AbstractOpenCloseChecker() { + fsm = initFSM(); + } + + public void processAst(IASTTranslationUnit ast) { + GraphCreator creator = new GraphCreator(); + + // Retrieve resource corresponding to this translation unit + String path = ast.getFilePath(); + URI fileURI = new File(path).toURI(); + IWorkspaceRoot wsRoot = ResourcesPlugin.getWorkspace().getRoot(); + IResource[] resources = wsRoot.findFilesForLocationURI(fileURI); + if (resources != null && resources.length > 0) { + IProject proj = resources[0].getProject(); + + // Create call graph for project + ICallGraph cg = creator.createCallGraph(proj); + creator.computeCallGraph(cg); + + // Create control flow graph for each function + for (ICallGraphNode node : cg.getAllNodes()) { + IASTStatement fnBody = node.getFuncDef().getBody(); + IControlFlowGraph cfg = new ControlFlowGraph(fnBody); + cfg.buildCFG(); + + // Search for error states using property simulation algorithm + PropertySimulator sim = new PropertySimulator(cfg, fsm); + + // Check if the exit edge of the CFG contains an error state + for (SymbolicState s : sim.getEndStates()) { + if (s.getPropertyStates().contains(error)) { + // Report problems + for (IASTNode errorNode : s.getErrorCauses()) { + reportProblem(errorNode, s.getExecutionState()); + } + } + } + } + } + } + + private IPropertyFSM initFSM() { + uninit = new PropertyState("$u") { + @Override + public PropertyState transition(IASTNode node) { + PropertyState dest = uninit; + if (containsOpen(node)) { + dest = opened; + } + else if (containsClose(node)) { + dest = error; + } + return dest; + } + }; + + opened = new PropertyState("o") { + @Override + public PropertyState transition(IASTNode node) { + PropertyState dest = opened; + if (containsOpen(node)) { + dest = error; + } + if (containsClose(node)) { + dest = uninit; + } + return dest; + } + }; + + error = new PropertyState("$e") { + + @Override + public PropertyState transition(IASTNode node) { + return error; + } + }; + + return new IPropertyFSM() { + + @Override + public PropertyState getUninitState() { + return uninit; + } + + @Override + public Set<PropertyState> getPropertyStates() { + Set<PropertyState> states = new HashSet<PropertyState>(); + states.add(uninit); + states.add(opened); + states.add(error); + return states; + } + + @Override + public PropertyState getErrorState() { + return error; + } + }; + } + + protected abstract boolean containsOpen(IASTNode node); + + protected abstract boolean containsClose(IASTNode node); + + protected abstract void reportProblem(IASTNode node, ExecutionState condition); +} diff --git a/org.eclipse.cdt.codan.extension/src/org/eclipse/cdt/codan/extension/checkers/CloseOpenedFilesChecker.java b/org.eclipse.cdt.codan.extension/src/org/eclipse/cdt/codan/extension/checkers/CloseOpenedFilesChecker.java index d60889a..2117109 100644 --- a/org.eclipse.cdt.codan.extension/src/org/eclipse/cdt/codan/extension/checkers/CloseOpenedFilesChecker.java +++ b/org.eclipse.cdt.codan.extension/src/org/eclipse/cdt/codan/extension/checkers/CloseOpenedFilesChecker.java @@ -10,157 +10,31 @@ *******************************************************************************/ package org.eclipse.cdt.codan.extension.checkers; -import java.io.File; -import java.net.URI; import java.text.MessageFormat; -import java.util.HashSet; -import java.util.Set; -import org.eclipse.cdt.codan.core.model.AbstractIndexAstChecker; import org.eclipse.cdt.codan.extension.Activator; import org.eclipse.cdt.codan.extension.ExecutionState; -import org.eclipse.cdt.codan.extension.IPropertyFSM; -import org.eclipse.cdt.codan.extension.PropertySimulator; -import org.eclipse.cdt.codan.extension.PropertyState; -import org.eclipse.cdt.codan.extension.SymbolicState; import org.eclipse.cdt.core.dom.ast.IASTNode; -import org.eclipse.cdt.core.dom.ast.IASTStatement; -import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.resources.IWorkspaceRoot; -import org.eclipse.core.resources.ResourcesPlugin; -import org.eclipse.ptp.pldt.mpi.analysis.cdt.graphs.GraphCreator; -import org.eclipse.ptp.pldt.mpi.analysis.cdt.graphs.ICallGraph; -import org.eclipse.ptp.pldt.mpi.analysis.cdt.graphs.ICallGraphNode; -import org.eclipse.ptp.pldt.mpi.analysis.cdt.graphs.IControlFlowGraph; -import org.eclipse.ptp.pldt.mpi.analysis.cdt.graphs.impl.ControlFlowGraph; -public class CloseOpenedFilesChecker extends AbstractIndexAstChecker { - private static final String ERR_ID = Activator.PLUGIN_ID + ".CloseOpenedFilesProblem"; +public class CloseOpenedFilesChecker extends AbstractOpenCloseChecker { + private static final String ERR_ID = Activator.PLUGIN_ID + ".OpenCloseFilesProblem"; private static final String OPEN = "open"; private static final String CLOSE = "close"; - private IPropertyFSM fsm; - - // Property FSM states - private PropertyState uninit; - private PropertyState error; - private PropertyState opened; - - public CloseOpenedFilesChecker() { - fsm = initFSM(); - } - - public void processAst(IASTTranslationUnit ast) { - GraphCreator creator = new GraphCreator(); - - // Retrieve resource corresponding to this translation unit - String path = ast.getFilePath(); - URI fileURI = new File(path).toURI(); - IWorkspaceRoot wsRoot = ResourcesPlugin.getWorkspace().getRoot(); - IResource[] resources = wsRoot.findFilesForLocationURI(fileURI); - if (resources != null && resources.length > 0) { - IProject proj = resources[0].getProject(); - - // Create call graph for project - ICallGraph cg = creator.createCallGraph(proj); - creator.computeCallGraph(cg); - - // Create control flow graph for each function - for (ICallGraphNode node : cg.getAllNodes()) { - IASTStatement fnBody = node.getFuncDef().getBody(); - IControlFlowGraph cfg = new ControlFlowGraph(fnBody); - cfg.buildCFG(); - - // Search for error states using property simulation algorithm - PropertySimulator sim = new PropertySimulator(cfg, fsm); - - // Check if the exit edge of the CFG contains an error state - for (SymbolicState s : sim.getEndStates()) { - if (s.getPropertyStates().contains(error)) { - // Report problems - for (IASTNode errorNode : s.getErrorCauses()) { - reportProblem(errorNode, s.getExecutionState()); - } - } - } - } - } - } - - private IPropertyFSM initFSM() { - uninit = new PropertyState("$u") { - @Override - public PropertyState transition(IASTNode node) { - PropertyState dest = uninit; - if (containsOpen(node)) { - dest = opened; - } - else if (containsClose(node)) { - dest = error; - } - return dest; - } - }; - - opened = new PropertyState("o") { - @Override - public PropertyState transition(IASTNode node) { - PropertyState dest = opened; - if (containsOpen(node)) { - dest = error; - } - if (containsClose(node)) { - dest = uninit; - } - return dest; - } - }; - - error = new PropertyState("$e") { - - @Override - public PropertyState transition(IASTNode node) { - return error; - } - }; - - return new IPropertyFSM() { - - @Override - public PropertyState getUninitState() { - return uninit; - } - - @Override - public Set<PropertyState> getPropertyStates() { - Set<PropertyState> states = new HashSet<PropertyState>(); - states.add(uninit); - states.add(opened); - states.add(error); - return states; - } - - @Override - public PropertyState getErrorState() { - return error; - } - }; - } - + @Override protected boolean containsOpen(IASTNode node) { FunctionNameParser parser = new FunctionNameParser(node, OPEN, new String[] { "const char *", "int" }); return parser.matches(); } + @Override protected boolean containsClose(IASTNode node) { FunctionNameParser parser = new FunctionNameParser(node, CLOSE, new String[] { "int" }); return parser.matches(); } - - private void reportProblem(IASTNode node, ExecutionState condition) { + + protected void reportProblem(IASTNode node, ExecutionState condition) { String message; if (condition.isTop()) { message = "Improper use of open/close."; diff --git a/org.eclipse.cdt.codan.extension/src/org/eclipse/cdt/codan/extension/checkers/FOpenFCloseChecker.java b/org.eclipse.cdt.codan.extension/src/org/eclipse/cdt/codan/extension/checkers/FOpenFCloseChecker.java new file mode 100644 index 0000000..621a9eb --- /dev/null +++ b/org.eclipse.cdt.codan.extension/src/org/eclipse/cdt/codan/extension/checkers/FOpenFCloseChecker.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * Copyright (c) 2009 Elliott Baron + * 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: + * Elliott Baron - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.codan.extension.checkers; + +import java.text.MessageFormat; + +import org.eclipse.cdt.codan.extension.Activator; +import org.eclipse.cdt.codan.extension.ExecutionState; +import org.eclipse.cdt.core.dom.ast.IASTNode; + +public class FOpenFCloseChecker extends AbstractOpenCloseChecker { + private static final String ERR_ID = Activator.PLUGIN_ID + ".FOpenFCloseFilesProblem"; + + private static final String FOPEN = "fopen"; + private static final String FCLOSE = "fclose"; + + @Override + protected boolean containsOpen(IASTNode node) { + FunctionNameParser parser = new FunctionNameParser(node, FOPEN, new String[] { "const char * restrict", "const char * restrict" }); + return parser.matches(); + } + + @Override + protected boolean containsClose(IASTNode node) { + FunctionNameParser parser = new FunctionNameParser(node, FCLOSE, new String[] { "FILE *" }); + return parser.matches(); + } + + protected void reportProblem(IASTNode node, ExecutionState condition) { + String message; + if (condition.isTop()) { + message = "Improper use of fopen/fclose."; + } + else { + message = MessageFormat.format("Improper use of fopen/fclose given {0}.", condition); + } + reportProblem(ERR_ID, node, message); + } + +} diff --git a/org.eclipse.cdt.codan.extension/src/org/eclipse/cdt/codan/extension/checkers/FunctionNameParser.java b/org.eclipse.cdt.codan.extension/src/org/eclipse/cdt/codan/extension/checkers/FunctionNameParser.java index 22f4287..d02b2ce 100644 --- a/org.eclipse.cdt.codan.extension/src/org/eclipse/cdt/codan/extension/checkers/FunctionNameParser.java +++ b/org.eclipse.cdt.codan.extension/src/org/eclipse/cdt/codan/extension/checkers/FunctionNameParser.java @@ -65,7 +65,8 @@ public class FunctionNameParser { result = true; for (int i = 0; i < params.length; i++) { IType type = params[i].getType(); - result &= paramTypes[i].equals(ASTTypeUtil.getType(type)); + String actualType = ASTTypeUtil.getType(type, false); + result &= paramTypes[i].equals(actualType); } } } catch (DOMException e) { |