All Downloads are FREE. Search and download functionalities are using the official Maven repository.

it.unive.lisa.interprocedural.CFGResults Maven / Gradle / Ivy

package it.unive.lisa.interprocedural;

import it.unive.lisa.analysis.AbstractState;
import it.unive.lisa.analysis.CFGWithAnalysisResults;
import it.unive.lisa.analysis.SemanticException;
import it.unive.lisa.analysis.heap.HeapDomain;
import it.unive.lisa.analysis.lattices.FunctionalLattice;
import it.unive.lisa.analysis.value.ValueDomain;
import java.util.Collection;
import java.util.Map;
import org.apache.commons.lang3.tuple.Pair;

/**
 * A {@link FunctionalLattice} from {@link ContextSensitivityToken}s to
 * {@link CFGWithAnalysisResults}s. This class is meant to store fixpoint
 * results on each token generated during the interprocedural analysis.
 * 
 * @author Luca Negrini
 * 
 * @param  the type of {@link AbstractState} contained into the analysis
 *                state
 * @param  the type of {@link HeapDomain} contained into the computed
 *                abstract state
 * @param  the type of {@link ValueDomain} contained into the computed
 *                abstract state
 */
public class CFGResults,
		H extends HeapDomain,
		V extends ValueDomain>
		extends FunctionalLattice, ContextSensitivityToken, CFGWithAnalysisResults> {

	/**
	 * Builds a new result.
	 * 
	 * @param lattice a singleton instance used for retrieving top and bottom
	 *                    values
	 */
	public CFGResults(CFGWithAnalysisResults lattice) {
		super(lattice);
	}

	/**
	 * Builds a new result.
	 * 
	 * @param lattice a singleton instance used for retrieving top and bottom
	 *                    values
	 */
	private CFGResults(CFGWithAnalysisResults lattice,
			Map> function) {
		super(lattice, function);
	}

	/**
	 * Stores the result of a fixpoint computation on a cfg, if needed. This
	 * method returns a pair of a boolean and a {@link CFGWithAnalysisResults},
	 * where ({@code prev} is the {@link CFGWithAnalysisResults} already present
	 * for the given {@code token}):
	 * 
    *
  • if no {@code prev} was stored for {@code token}, than that token is * mapped to {@code result} and this method returns * {@code }
  • *
  • if {@code prev <= result}, then {@code token} is mapped to * {@code result} and this method returns {@code }
  • *
  • if {@code result <= prev}, then the mapping is left untouched and * this method returns {@code }
  • *
  • otherwise, {@code token} is mapped to {@code lub = prev.lub(result)} * and this method returns {@code }
  • *
* The value returned by this method is intended to be a hint that a new * fixpoint computation is needed to ensure that the results are stable. * * @param token the {@link ContextSensitivityToken} that identifying the * result * @param result the {@link CFGWithAnalysisResults} to store * * @return {@code true} if the previous result has been updated, if any * * @throws SemanticException if something goes wrong during the update */ public Pair> putResult(ContextSensitivityToken token, CFGWithAnalysisResults result) throws SemanticException { CFGWithAnalysisResults previousResult = function.get(token); if (previousResult == null) { // no previous result function.put(token, result); return Pair.of(false, result); } else if (previousResult.lessOrEqual(result)) { // previous is smaller than result if (result.lessOrEqual(previousResult)) // they are equal return Pair.of(false, previousResult); else { // result is bigger, store that instead function.put(token, result); return Pair.of(true, result); } } else if (result.lessOrEqual(previousResult)) { // result is smaller than previous return Pair.of(false, previousResult); } else { // result and previous are not comparable CFGWithAnalysisResults lub = previousResult.lub(result); function.put(token, lub); return Pair.of(true, lub); } } /** * Yields {@code true} if a result exists for the given {@code token}. * * @param token the {@link ContextSensitivityToken} that identifying the * result * * @return {@code true} if that condition holds */ public boolean contains(ContextSensitivityToken token) { return function != null && function.containsKey(token); } /** * Yields all the results stored in this object, for any possible * {@link ContextSensitivityToken} used. * * @return the results */ public Collection> getAll() { return function.values(); } @Override public CFGResults top() { return new CFGResults<>(lattice.top()); } @Override public boolean isTop() { return lattice.isTop() && (function == null || function.isEmpty()); } @Override public CFGResults bottom() { return new CFGResults<>(lattice.bottom()); } @Override public boolean isBottom() { return lattice.isBottom() && (function == null || function.isEmpty()); } @Override protected CFGResults mk(CFGWithAnalysisResults lattice, Map> function) { return new CFGResults<>(lattice, function); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy