Package edu.cmu.cs.crystal.analysis.npe.annotations

Source Code of edu.cmu.cs.crystal.analysis.npe.annotations.NPEAnnotatedTransferFunction

package edu.cmu.cs.crystal.analysis.npe.annotations;

import org.eclipse.jdt.core.dom.MethodDeclaration;
import org.eclipse.jdt.core.dom.SingleVariableDeclaration;

import edu.cmu.cs.crystal.annotations.AnnotationDatabase;
import edu.cmu.cs.crystal.annotations.AnnotationSummary;
import edu.cmu.cs.crystal.flow.ILatticeOperations;
import edu.cmu.cs.crystal.simple.AbstractingTransferFunction;
import edu.cmu.cs.crystal.simple.TupleLatticeElement;
import edu.cmu.cs.crystal.simple.TupleLatticeOperations;
import edu.cmu.cs.crystal.tac.model.ArrayInitInstruction;
import edu.cmu.cs.crystal.tac.model.CopyInstruction;
import edu.cmu.cs.crystal.tac.model.LoadLiteralInstruction;
import edu.cmu.cs.crystal.tac.model.MethodCallInstruction;
import edu.cmu.cs.crystal.tac.model.NewArrayInstruction;
import edu.cmu.cs.crystal.tac.model.NewObjectInstruction;
import edu.cmu.cs.crystal.tac.model.Variable;

public class NPEAnnotatedTransferFunction extends AbstractingTransferFunction<TupleLatticeElement<Variable, NullLatticeElement>> {
  /**
   * The operations for this lattice. We want to have a tuple lattice from variables to null lattice elements, so we
   * give it an instance of NullLatticeOperations. We also want the default value to be maybe null.
   */
  TupleLatticeOperations<Variable, NullLatticeElement> ops =
    new TupleLatticeOperations<Variable, NullLatticeElement>(new NullLatticeOperations(), NullLatticeElement.MAYBE_NULL);
  private AnnotationDatabase annoDB;
 
  public NPEAnnotatedTransferFunction(AnnotationDatabase annoDB) {
    this.annoDB = annoDB;
  }

  /**
   * The operations will create a default lattice which will map all variables to maybe null (since that was our default).
   *
   * Of course, "this" should never be null.
   */
  public TupleLatticeElement<Variable, NullLatticeElement> createEntryValue(
      MethodDeclaration method) {
    TupleLatticeElement<Variable, NullLatticeElement> def = ops.getDefault();
    def.put(getAnalysisContext().getThisVariable(), NullLatticeElement.NOT_NULL);
   
    AnnotationSummary summary = annoDB.getSummaryForMethod(method.resolveBinding());
   
    for (int ndx = 0; ndx < method.parameters().size(); ndx++) {
      SingleVariableDeclaration decl = (SingleVariableDeclaration) method.parameters().get(ndx);
      Variable paramVar = getAnalysisContext().getSourceVariable(decl.resolveBinding());
     
      if (summary.getParameter(ndx, AnnotatedNPEAnalysis.NON_NULL_ANNO) != null) //is this parameter annotated with @Nonnull?
        def.put(paramVar, NullLatticeElement.NOT_NULL);
    }
   
    return def;
  }

  /**
   * Just return our lattice ops.
   */
  public ILatticeOperations<TupleLatticeElement<Variable, NullLatticeElement>> getLatticeOperations() {
    return ops;
  }

  @Override
  public TupleLatticeElement<Variable, NullLatticeElement> transfer(
      ArrayInitInstruction instr,
      TupleLatticeElement<Variable, NullLatticeElement> value) {
    value.put(instr.getTarget(), NullLatticeElement.NOT_NULL);
    return value;
  }

  @Override
  public TupleLatticeElement<Variable, NullLatticeElement> transfer(
      CopyInstruction instr,
      TupleLatticeElement<Variable, NullLatticeElement> value) {
    value.put(instr.getTarget(), value.get(instr.getOperand()));
    return value;
  }

  @Override
  public TupleLatticeElement<Variable, NullLatticeElement> transfer(
      LoadLiteralInstruction instr,
      TupleLatticeElement<Variable, NullLatticeElement> value) {
    if (instr.isNull())
      value.put(instr.getTarget(), NullLatticeElement.NULL);
    else
      value.put(instr.getTarget(), NullLatticeElement.NOT_NULL);
    return value;
  }

  @Override
  public TupleLatticeElement<Variable, NullLatticeElement> transfer(
      MethodCallInstruction instr,
      TupleLatticeElement<Variable, NullLatticeElement> value) {
    AnnotationSummary summary = annoDB.getSummaryForMethod(instr.resolveBinding());
   
    for (int ndx = 0; ndx < instr.getArgOperands().size(); ndx++) {
      Variable paramVar = instr.getArgOperands().get(ndx);
     
      if (summary.getParameter(ndx, AnnotatedNPEAnalysis.NON_NULL_ANNO) != null) //is this parameter annotated with @Nonnull?
        value.put(paramVar, NullLatticeElement.NOT_NULL);
    }
   
    if (summary.getReturn(AnnotatedNPEAnalysis.NON_NULL_ANNO) != null)
      value.put(instr.getTarget(), NullLatticeElement.NOT_NULL);
   
    //clearly, the receiver is not null if this method call does actually occur ;)
    value.put(instr.getReceiverOperand(), NullLatticeElement.NOT_NULL);

    return value;
  }

  @Override
  public TupleLatticeElement<Variable, NullLatticeElement> transfer(
      NewArrayInstruction instr,
      TupleLatticeElement<Variable, NullLatticeElement> value) {
    value.put(instr.getTarget(), NullLatticeElement.NOT_NULL);
    return value;
  }

  @Override
  public TupleLatticeElement<Variable, NullLatticeElement> transfer(
      NewObjectInstruction instr,
      TupleLatticeElement<Variable, NullLatticeElement> value) {
    value.put(instr.getTarget(), NullLatticeElement.NOT_NULL);
    return value;
  }
}
TOP

Related Classes of edu.cmu.cs.crystal.analysis.npe.annotations.NPEAnnotatedTransferFunction

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.