summaryrefslogtreecommitdiffstats
path: root/org.eclipse.cdt.codan.extension/src/org/eclipse/cdt/codan/extension/checkers/AbstractOpenCloseChecker.java
diff options
context:
space:
mode:
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.java151
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);
+}