package org.jakstab.analysis.rd; import java.util.Collections; import java.util.Set; import org.jakstab.AnalysisProperties; import org.jakstab.analysis.*; import org.jakstab.cfa.CFAEdge; import org.jakstab.cfa.Location; import org.jakstab.rtl.statements.*; import org.jakstab.util.Logger; /** * Demo analysis for classroom use. * * Template for a reaching definitions analysis based on the CPA framework. All methods that need to * be implemented are marked with TODO. */ public class ReachingDefinitionsAnalysis extends SimpleCPA implements ConfigurableProgramAnalysis { private static final Logger logger = Logger.getLogger(ReachingDefinitionsAnalysis.class); public static void register(AnalysisProperties p) { // This registers the analysis with the framework p.setShortHand('r'); p.setName("Reaching definitions analysis"); p.setDescription("For each program point, calculate the set of variable definitions that reach it."); p.setExplicit(false); } @Override public AbstractState initStartState(Location location) { // TODO Return the initial state for a program entry location "label" here. return new RDState(); // Dummy } @Override public AbstractState merge(AbstractState s1, AbstractState s2) { // TODO Implement the merge operator return s2; // Dummy } @Override public Set<AbstractState> post(AbstractState state, CFAEdge edge) { // TODO Implement the abstract transfer relation. // Read statement from control flow edge RTLStatement statement = (RTLStatement)edge.getTransformer(); // Cast the current abstract state to it's type final RDState curState = (RDState)state; // Calculate the set of abstract successors using a visitor pattern // The DefaultStatementVisitor throws exceptions on every not overridden visit method Set<AbstractState> abstractSuccessors = statement.accept(new DefaultStatementVisitor<Set<AbstractState>>() { @Override protected Set<AbstractState> visitDefault(RTLStatement stmt) { // Just return the same state for unsupported statements. return Collections.singleton((AbstractState)curState); } @Override public Set<AbstractState> visit(RTLVariableAssignment stmt) { // TODO Implement transfer function for assignments logger.info("Processing assignment at " + stmt.getLabel() + ": " + stmt.toString()); return Collections.singleton((AbstractState)curState); // Dummy } @Override public Set<AbstractState> visit(RTLAssume stmt) { // TODO Implement transfer function for assume logger.info("Processing assume at " + stmt.getLabel() + ": " + stmt.toString()); return Collections.singleton((AbstractState)curState); // Dummy } }); return abstractSuccessors; } @Override public boolean stop(AbstractState s, ReachedSet reached) { // TODO Implement stop operator // You can use the following template, but since // lessOrEqual in RDState currently always returns // false, the analysis would never terminate. // for (AbstractState a : reached) { // if (s.lessOrEqual(a)) { // return true; // } // } // return false; return true; // Dummy } }