diff options
Diffstat (limited to 'org.eclipse.cdt.codan.extension/src/org/eclipse/cdt/codan/extension/checkers/AbstractOpenCloseChecker.java')
-rw-r--r-- | org.eclipse.cdt.codan.extension/src/org/eclipse/cdt/codan/extension/checkers/AbstractOpenCloseChecker.java | 151 |
1 files changed, 151 insertions, 0 deletions
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); +} |