Extended exceptionan anlysis with exception filter.
This commit is contained in:
parent
77b1ed71c7
commit
bed18b792c
|
@ -19,28 +19,39 @@ import com.ibm.wala.ipa.callgraph.CGNode;
|
|||
import com.ibm.wala.ipa.callgraph.CallGraph;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.InstanceKey;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.PointerAnalysis;
|
||||
import com.ibm.wala.ipa.cfg.exceptionpruning.interprocedural.InterproceduralExceptionFilter;
|
||||
import com.ibm.wala.ipa.cha.ClassHierarchy;
|
||||
import com.ibm.wala.ssa.SSAInstruction;
|
||||
import com.ibm.wala.types.TypeReference;
|
||||
import com.ibm.wala.util.CancelException;
|
||||
import com.ibm.wala.util.graph.Graph;
|
||||
import com.ibm.wala.util.graph.impl.InvertedGraph;
|
||||
import com.ibm.wala.util.graph.impl.SelfLoopAddedGraph;
|
||||
|
||||
public class ExceptionAnalysis {
|
||||
public class ExceptionAnalysis {
|
||||
private BitVectorSolver<CGNode> solver;
|
||||
private ExceptionToBitvectorTransformer transformer;
|
||||
|
||||
public ExceptionAnalysis(CallGraph callgraph, PointerAnalysis<InstanceKey> pointerAnalysis, ClassHierarchy cha){
|
||||
IntraproceduralResult intraResult = new IntraproceduralResult(callgraph, pointerAnalysis, cha);
|
||||
transformer = new ExceptionToBitvectorTransformer(intraResult.getExceptions());
|
||||
ExceptionTransferFunctionProvider transferFunctionProvider = new ExceptionTransferFunctionProvider(intraResult, callgraph, transformer);
|
||||
|
||||
|
||||
public ExceptionAnalysis(CallGraph callgraph, PointerAnalysis<InstanceKey> pointerAnalysis, ClassHierarchy cha) {
|
||||
this(callgraph, pointerAnalysis, cha, null);
|
||||
}
|
||||
|
||||
public ExceptionAnalysis(CallGraph callgraph, PointerAnalysis<InstanceKey> pointerAnalysis, ClassHierarchy cha,
|
||||
InterproceduralExceptionFilter<SSAInstruction> filter) {
|
||||
IntraproceduralResult intraResult = new IntraproceduralResult(callgraph, pointerAnalysis, cha, filter);
|
||||
transformer = new ExceptionToBitvectorTransformer(intraResult.getExceptions());
|
||||
ExceptionTransferFunctionProvider transferFunctionProvider = new ExceptionTransferFunctionProvider(intraResult, callgraph,
|
||||
transformer);
|
||||
|
||||
Graph<CGNode> graph = new SelfLoopAddedGraph<>(new InvertedGraph<CGNode>(callgraph));
|
||||
BitVectorFramework<CGNode, TypeReference> problem = new BitVectorFramework<>(graph, transferFunctionProvider, transformer.getValues());
|
||||
|
||||
|
||||
BitVectorFramework<CGNode, TypeReference> problem = new BitVectorFramework<>(graph, transferFunctionProvider,
|
||||
transformer.getValues());
|
||||
|
||||
solver = new ExceptionFlowSolver(problem, intraResult, transformer);
|
||||
solver.initForFirstSolve();
|
||||
}
|
||||
|
||||
public void solve() {
|
||||
try {
|
||||
solver.solve(null);
|
||||
} catch (CancelException e) {
|
||||
|
@ -48,8 +59,8 @@ public class ExceptionAnalysis {
|
|||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public Set<TypeReference> getCGNodeExceptions(CGNode node){
|
||||
|
||||
public Set<TypeReference> getCGNodeExceptions(CGNode node) {
|
||||
BitVectorVariable nodeResult = solver.getIn(node);
|
||||
if (nodeResult != null) {
|
||||
return transformer.computeExceptions(nodeResult);
|
||||
|
|
|
@ -85,14 +85,12 @@ public class ExceptionTransferFunctionProvider implements ITransferFunctionProvi
|
|||
Iterator<CallSiteReference> callsites = cg.getPossibleSites(src, dst);
|
||||
BitVector filtered = new BitVector(transformer.getValues().getSize());
|
||||
|
||||
if (callsites.hasNext()) {
|
||||
System.out.println(src.getMethod().toString() + " -> " + dst.getMethod().toString());
|
||||
|
||||
if (callsites.hasNext()) {
|
||||
CallSiteReference callsite = callsites.next();
|
||||
filtered = transformer.computeBitVector(intraResult.getFilteredExceptions(src, callsite));
|
||||
filtered = transformer.computeBitVector(intraResult.getCaughtExceptions(src, callsite));
|
||||
while (callsites.hasNext()) {
|
||||
callsite = callsites.next();
|
||||
BitVector bv = transformer.computeBitVector(intraResult.getFilteredExceptions(src, callsite));
|
||||
BitVector bv = transformer.computeBitVector(intraResult.getCaughtExceptions(src, callsite));
|
||||
filtered.and(bv);
|
||||
}
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
*******************************************************************************/
|
||||
package com.ibm.wala.analysis.exceptionanalysis;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
|
@ -21,12 +22,13 @@ import java.util.Set;
|
|||
|
||||
import com.ibm.wala.classLoader.CallSiteReference;
|
||||
import com.ibm.wala.classLoader.IClass;
|
||||
import com.ibm.wala.classLoader.IMethod;
|
||||
import com.ibm.wala.ipa.callgraph.CGNode;
|
||||
import com.ibm.wala.ipa.callgraph.CallGraph;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.InstanceKey;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.PointerAnalysis;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.PointerKey;
|
||||
import com.ibm.wala.ipa.cfg.exceptionpruning.FilteredException;
|
||||
import com.ibm.wala.ipa.cfg.exceptionpruning.interprocedural.InterproceduralExceptionFilter;
|
||||
import com.ibm.wala.ipa.cha.ClassHierarchy;
|
||||
import com.ibm.wala.ssa.IR;
|
||||
import com.ibm.wala.ssa.ISSABasicBlock;
|
||||
|
@ -44,11 +46,14 @@ public class IntraproceduralResult {
|
|||
private CallGraph callGraph;
|
||||
private PointerAnalysis<InstanceKey> pointerAnalysis;
|
||||
private ClassHierarchy classHierachy;
|
||||
private InterproceduralExceptionFilter<SSAInstruction> filter;
|
||||
|
||||
public IntraproceduralResult(CallGraph cg, PointerAnalysis<InstanceKey> pointerAnalysis, ClassHierarchy cha) {
|
||||
public IntraproceduralResult(CallGraph cg, PointerAnalysis<InstanceKey> pointerAnalysis, ClassHierarchy cha,
|
||||
InterproceduralExceptionFilter<SSAInstruction> filter) {
|
||||
this.callGraph = cg;
|
||||
this.pointerAnalysis = pointerAnalysis;
|
||||
this.classHierachy = cha;
|
||||
this.filter = filter;
|
||||
intraproceduralExceptions = new HashMap<>();
|
||||
exceptions = new HashSet<>();
|
||||
compute();
|
||||
|
@ -64,14 +69,13 @@ public class IntraproceduralResult {
|
|||
for (ISSABasicBlock block : ir.getControlFlowGraph()) {
|
||||
SSAInstruction throwingInstruction = getThrowingInstruction(block);
|
||||
if (throwingInstruction != null) {
|
||||
Set<TypeReference> caughtExceptions = collectCaughtExceptions(node, block);
|
||||
Set<TypeReference> thrownExceptions = collectThrownExceptions(node, throwingInstruction);
|
||||
Set<TypeReference> caughtExceptions = collectCaughtExceptions(node, block);
|
||||
Set<TypeReference> filteredExceptions = collectFilteredExceptions(node, throwingInstruction);
|
||||
|
||||
Set<TypeReference> exceptions = computeThrownMinusCaughtExceptions(thrownExceptions, caughtExceptions);
|
||||
if (node.getMethod().getName().toString().equals("foo") && !exceptions.isEmpty()) {
|
||||
System.out.println(throwingInstruction);
|
||||
}
|
||||
intraproceduralExceptions.get(node).addAll(exceptions);
|
||||
thrownExceptions.removeAll(filteredExceptions);
|
||||
thrownExceptions.removeAll(caughtExceptions);
|
||||
intraproceduralExceptions.get(node).addAll(thrownExceptions);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -82,14 +86,24 @@ public class IntraproceduralResult {
|
|||
}
|
||||
}
|
||||
|
||||
private Set<TypeReference> computeThrownMinusCaughtExceptions(Set<TypeReference> thrownExceptions,
|
||||
Set<TypeReference> caughtExceptions) {
|
||||
Set<TypeReference> result = new LinkedHashSet<>();
|
||||
private Set<TypeReference> collectFilteredExceptions(CGNode node, SSAInstruction throwingInstruction) {
|
||||
if (filter != null) {
|
||||
Set<TypeReference> filtered = new LinkedHashSet<>();
|
||||
Collection<FilteredException> filters = filter.getFilter(node).filteredExceptions(throwingInstruction);
|
||||
for (FilteredException filter : filters) {
|
||||
if (filter.isSubclassFiltered()) {
|
||||
for (IClass iclass : this.classHierachy.computeSubClasses(filter.getException())) {
|
||||
filtered.add(iclass.getReference());
|
||||
}
|
||||
} else {
|
||||
filtered.add(filter.getException());
|
||||
}
|
||||
}
|
||||
return filtered;
|
||||
} else {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
result.addAll(thrownExceptions);
|
||||
result.removeAll(caughtExceptions);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -193,7 +207,7 @@ public class IntraproceduralResult {
|
|||
return result;
|
||||
}
|
||||
|
||||
public Set<TypeReference> getFilteredExceptions(CGNode node, CallSiteReference callsite) {
|
||||
public Set<TypeReference> getCaughtExceptions(CGNode node, CallSiteReference callsite) {
|
||||
Set<TypeReference> result = new LinkedHashSet<>();
|
||||
|
||||
IntSet iindices = node.getIR().getCallInstructionIndices(callsite);
|
||||
|
@ -206,10 +220,6 @@ public class IntraproceduralResult {
|
|||
throw new IllegalArgumentException("The given callsite dose not correspond to an invoke instruction." + instruction);
|
||||
}
|
||||
|
||||
// SSAInvokeInstruction invoke = (SSAInvokeInstruction) instruction;
|
||||
// if (instruction == null) {
|
||||
// throw new IllegalStateException();
|
||||
// }
|
||||
ISSABasicBlock block = node.getIR().getBasicBlockForInstruction(instruction);
|
||||
if (result.isEmpty()) {
|
||||
result.addAll(collectCaughtExceptions(node, block));
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2007 IBM Corporation.
|
||||
* 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:
|
||||
* IBM Corporation - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package com.ibm.wala.ipa.cfg.exceptionpruning.interprocedural;
|
||||
|
||||
import com.ibm.wala.analysis.arraybounds.ArrayOutOfBoundsAnalysis;
|
||||
import com.ibm.wala.ipa.callgraph.CGNode;
|
||||
import com.ibm.wala.ipa.cfg.exceptionpruning.ExceptionFilter;
|
||||
import com.ibm.wala.ipa.cfg.exceptionpruning.filter.ArrayOutOfBoundFilter;
|
||||
import com.ibm.wala.ssa.SSAInstruction;
|
||||
|
||||
public class ArrayOutOfBoundInterFilter extends StoringExceptionFilter<SSAInstruction>{
|
||||
|
||||
@Override
|
||||
protected ExceptionFilter<SSAInstruction> computeFilter(CGNode node) {
|
||||
ArrayOutOfBoundsAnalysis analysis = new ArrayOutOfBoundsAnalysis(node.getIR());
|
||||
return new ArrayOutOfBoundFilter(analysis);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2007 IBM Corporation.
|
||||
* 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:
|
||||
* IBM Corporation - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package com.ibm.wala.ipa.cfg.exceptionpruning.interprocedural;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedList;
|
||||
|
||||
import com.ibm.wala.ipa.callgraph.CGNode;
|
||||
import com.ibm.wala.ipa.cfg.exceptionpruning.ExceptionFilter;
|
||||
import com.ibm.wala.ipa.cfg.exceptionpruning.filter.CombinedExceptionFilter;
|
||||
|
||||
public class CombinedInterproceduralExceptionFilter<Instruction> implements InterproceduralExceptionFilter<Instruction> {
|
||||
private final Collection<InterproceduralExceptionFilter<Instruction>> filter;
|
||||
|
||||
public CombinedInterproceduralExceptionFilter() {
|
||||
this.filter = new LinkedList<>();
|
||||
}
|
||||
|
||||
public CombinedInterproceduralExceptionFilter(
|
||||
Collection<InterproceduralExceptionFilter<Instruction>> filter) {
|
||||
this.filter = filter;
|
||||
}
|
||||
|
||||
public boolean add(InterproceduralExceptionFilter<Instruction> e) {
|
||||
return this.filter.add(e);
|
||||
}
|
||||
|
||||
public boolean addAll(
|
||||
Collection<? extends InterproceduralExceptionFilter<Instruction>> c) {
|
||||
return this.filter.addAll(c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExceptionFilter<Instruction> getFilter(CGNode node) {
|
||||
CombinedExceptionFilter<Instruction> result = new CombinedExceptionFilter<Instruction>();
|
||||
for (InterproceduralExceptionFilter<Instruction> exceptionFilter:filter) {
|
||||
result.add(exceptionFilter.getFilter(node));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2007 IBM Corporation.
|
||||
* 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:
|
||||
* IBM Corporation - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package com.ibm.wala.ipa.cfg.exceptionpruning.interprocedural;
|
||||
|
||||
import com.ibm.wala.ipa.callgraph.CGNode;
|
||||
import com.ibm.wala.ipa.cfg.exceptionpruning.ExceptionFilter;
|
||||
|
||||
public class IgnoreExceptionsInterFilter<Instruction> implements InterproceduralExceptionFilter<Instruction>{
|
||||
private ExceptionFilter<Instruction> filter;
|
||||
|
||||
public IgnoreExceptionsInterFilter(ExceptionFilter<Instruction> filter){
|
||||
this.filter = filter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExceptionFilter<Instruction> getFilter(CGNode node) {
|
||||
return filter;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2007 IBM Corporation.
|
||||
* 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:
|
||||
* IBM Corporation - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package com.ibm.wala.ipa.cfg.exceptionpruning.interprocedural;
|
||||
|
||||
import com.ibm.wala.ipa.callgraph.CGNode;
|
||||
import com.ibm.wala.ipa.cfg.exceptionpruning.ExceptionFilter;
|
||||
|
||||
public interface InterproceduralExceptionFilter<Instruction> {
|
||||
public ExceptionFilter<Instruction> getFilter(CGNode node);
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2007 IBM Corporation.
|
||||
* 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:
|
||||
* IBM Corporation - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package com.ibm.wala.ipa.cfg.exceptionpruning.interprocedural;
|
||||
|
||||
import com.ibm.wala.analysis.nullpointer.IntraproceduralNullPointerAnalysis;
|
||||
import com.ibm.wala.ipa.callgraph.CGNode;
|
||||
import com.ibm.wala.ipa.cfg.exceptionpruning.ExceptionFilter;
|
||||
import com.ibm.wala.ipa.cfg.exceptionpruning.filter.NullPointerExceptionFilter;
|
||||
import com.ibm.wala.ssa.SSAInstruction;
|
||||
|
||||
public class NullPointerExceptionInterFilter extends StoringExceptionFilter<SSAInstruction>{
|
||||
|
||||
@Override
|
||||
protected ExceptionFilter<SSAInstruction> computeFilter(CGNode node) {
|
||||
IntraproceduralNullPointerAnalysis analysis = new IntraproceduralNullPointerAnalysis(node.getIR());
|
||||
return new NullPointerExceptionFilter(analysis);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2007 IBM Corporation.
|
||||
* 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:
|
||||
* IBM Corporation - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package com.ibm.wala.ipa.cfg.exceptionpruning.interprocedural;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.ibm.wala.ipa.callgraph.CGNode;
|
||||
import com.ibm.wala.ipa.cfg.exceptionpruning.ExceptionFilter;
|
||||
|
||||
public abstract class StoringExceptionFilter<Instruction> implements InterproceduralExceptionFilter<Instruction>{
|
||||
private Map<CGNode, ExceptionFilter<Instruction>> store;
|
||||
|
||||
public StoringExceptionFilter(){
|
||||
this.store = new LinkedHashMap<>();
|
||||
}
|
||||
|
||||
abstract protected ExceptionFilter<Instruction> computeFilter(CGNode node);
|
||||
|
||||
@Override
|
||||
public ExceptionFilter<Instruction> getFilter(CGNode node) {
|
||||
if (store.containsKey(node)) {
|
||||
return store.get(node);
|
||||
} else {
|
||||
ExceptionFilter<Instruction> filter = computeFilter(node);
|
||||
store.put(node, filter);
|
||||
return filter;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
/**
|
||||
*
|
||||
*/
|
||||
/**
|
||||
* @author stephan
|
||||
*
|
||||
*/
|
||||
package com.ibm.wala.ipa.cfg.exceptionpruning.interprocedural;
|
Loading…
Reference in New Issue