/**
* This file is licensed under the University of Illinois/NCSA Open Source License. See LICENSE.TXT for details.
*/
package edu.illinois.keshmesh.detector;
import java.util.Iterator;
import com.ibm.wala.classLoader.CallSiteReference;
import com.ibm.wala.dataflow.graph.AbstractMeetOperator;
import com.ibm.wala.dataflow.graph.BitVectorIdentity;
import com.ibm.wala.dataflow.graph.BitVectorKillAll;
import com.ibm.wala.dataflow.graph.BitVectorUnion;
import com.ibm.wala.dataflow.graph.BitVectorUnionVector;
import com.ibm.wala.dataflow.graph.ITransferFunctionProvider;
import com.ibm.wala.fixpoint.BitVectorVariable;
import com.ibm.wala.fixpoint.UnaryOperator;
import com.ibm.wala.ipa.callgraph.CGNode;
import com.ibm.wala.ssa.IR;
import com.ibm.wala.util.intset.IntIterator;
import com.ibm.wala.util.intset.IntSet;
import edu.illinois.keshmesh.detector.util.AnalysisUtils;
/**
*
* @author Mohsen Vakilian
* @author Stas Negara
*
*/
public class LCK06JTransferFunctionProvider implements ITransferFunctionProvider<CGNode, BitVectorVariable> {
private final LCK06JBugDetector lck06jBugDetector;
public LCK06JTransferFunctionProvider(LCK06JBugDetector lck06BugDetector) {
this.lck06jBugDetector = lck06BugDetector;
}
@Override
public AbstractMeetOperator<BitVectorVariable> getMeetOperator() {
return BitVectorUnion.instance();
}
@Override
public boolean hasEdgeTransferFunctions() {
return true;
}
@Override
public UnaryOperator<BitVectorVariable> getEdgeTransferFunction(CGNode src, CGNode dst) {
if (!lck06jBugDetector.isSafeSynchronized(dst)) {
CGNodeInfo dstNodeInfo = lck06jBugDetector.getCGNodeInfoMap().get(dst);
Iterator<CallSiteReference> callSitesIterator = lck06jBugDetector.basicAnalysisData.callGraph.getPossibleSites(dst, src);
IR dstIR = dst.getIR();
while (callSitesIterator.hasNext()) {
CallSiteReference callSiteReference = callSitesIterator.next();
IntSet callInstructionIndices = dstIR.getCallInstructionIndices(callSiteReference);
IntIterator instructionIndicesIterator = callInstructionIndices.intIterator();
while (instructionIndicesIterator.hasNext()) {
int invokeInstructionIndex = instructionIndicesIterator.next();
InstructionInfo instructionInfo = new InstructionInfo(lck06jBugDetector.javaProject, dst, invokeInstructionIndex);
if (!AnalysisUtils.isProtectedByAnySynchronizedBlock(dstNodeInfo.getSafeSynchronizedBlocks(), instructionInfo)) {
return BitVectorIdentity.instance();
}
}
}
}
return BitVectorKillAll.instance();
}
@Override
public boolean hasNodeTransferFunctions() {
return true;
}
@Override
public UnaryOperator<BitVectorVariable> getNodeTransferFunction(CGNode node) {
return new BitVectorUnionVector(lck06jBugDetector.getCGNodeInfoMap().get(node).getBitVector());
}
}