Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 65 additions & 0 deletions idealPDS/src/main/java/typestate/ChainingBackwardFlowFunction.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/**
* *****************************************************************************
* Copyright (c) 2018 Fraunhofer IEM, Paderborn, Germany
* <p>
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
* <p>
* SPDX-License-Identifier: EPL-2.0
* <p>
* Contributors:
* Johannes Spaeth - initial API and implementation
* *****************************************************************************
*/
package typestate;

import boomerang.flowfunction.DefaultBackwardFlowFunction;
import boomerang.options.IAllocationSite;
import boomerang.scope.ControlFlowGraph;
import boomerang.scope.DeclaredMethod;
import boomerang.scope.InvokeExpr;
import boomerang.scope.Statement;
import boomerang.scope.Val;
import boomerang.solver.Strategies;
import boomerang.utils.MethodWrapper;
import java.util.Collection;
import java.util.LinkedHashSet;
import sync.pds.solver.nodes.Node;
import wpds.interfaces.State;

public class ChainingBackwardFlowFunction extends DefaultBackwardFlowFunction {

private final Collection<MethodWrapper> methodChains;

public ChainingBackwardFlowFunction(
IAllocationSite allocationSite,
Strategies strategies,
Collection<MethodWrapper> methodChains) {
super(allocationSite, strategies);

this.methodChains = methodChains;
}

@Override
public Collection<State> callToReturnFlow(
ControlFlowGraph.Edge currEdge, ControlFlowGraph.Edge nextEdge, Val fact) {
Collection<State> out = new LinkedHashSet<>(super.callToReturnFlow(currEdge, nextEdge, fact));

Statement statement = nextEdge.getTarget();
if (statement.isAssignStmt() && statement.containsInvokeExpr()) {
InvokeExpr invokeExpr = statement.getInvokeExpr();
DeclaredMethod declaredMethod = invokeExpr.getDeclaredMethod();

if (methodChains.contains(declaredMethod.toMethodWrapper())) {
Val leftOp = statement.getLeftOp();

if (leftOp.equals(fact) && invokeExpr.isInstanceInvokeExpr()) {
out.add(new Node<>(nextEdge, invokeExpr.getBase()));
}
}
}

return out;
}
}
75 changes: 75 additions & 0 deletions idealPDS/src/main/java/typestate/ChainingFlowFunctionFactory.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/**
* *****************************************************************************
* Copyright (c) 2018 Fraunhofer IEM, Paderborn, Germany
* <p>
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
* <p>
* SPDX-License-Identifier: EPL-2.0
* <p>
* Contributors:
* Johannes Spaeth - initial API and implementation
* *****************************************************************************
*/
package typestate;

import boomerang.flowfunction.DefaultFlowFunctionFactory;
import boomerang.flowfunction.IBackwardFlowFunction;
import boomerang.flowfunction.IForwardFlowFunction;
import boomerang.options.BoomerangOptions;
import boomerang.scope.FrameworkScope;
import boomerang.solver.BackwardBoomerangSolver;
import boomerang.solver.ForwardBoomerangSolver;
import boomerang.solver.Strategies;
import boomerang.utils.MethodWrapper;
import java.util.Collection;

/**
* Flow function factory that extends the {@link DefaultFlowFunctionFactory} by adding features to
* deal with chained methods when applying the call-to-return flow. Intermediate representations
* transform chained method calls into multiple statements and introduce new locals for each
* intermediate call. Although the chained calls return the original objects (i.e. an alias), the
* default flow function do not find the aliases. The extension in this flow function factory adds
* the functionality to collect corresponding aliases, too.
*
* <p>For example, a program
*
* <pre>{@code
* l.chain().chain();
* }</pre>
*
* is transformed into the intermediate representation
*
* <pre>{@code
* $s0 = l.chain();
* $s1 = $s0.chain();
* }</pre>
*
* The extended flow functions make sure to collect $s0 and $s1 as alias s.t. the analysis can
* collect the second call to chain().
*/
public class ChainingFlowFunctionFactory extends DefaultFlowFunctionFactory {

private final Collection<MethodWrapper> methodChains;

public ChainingFlowFunctionFactory(Collection<MethodWrapper> methodChains) {
this.methodChains = methodChains;
}

@Override
public IForwardFlowFunction createForwardFlowFunction(
FrameworkScope frameworkScope, BoomerangOptions options, ForwardBoomerangSolver<?> solver) {
Strategies strategies = createStrategies(frameworkScope, options, solver);

return new ChainingForwardFlowFunction(strategies, methodChains);
}

@Override
public IBackwardFlowFunction createBackwardFlowFunction(
FrameworkScope frameworkScope, BoomerangOptions options, BackwardBoomerangSolver<?> solver) {
Strategies strategies = createStrategies(frameworkScope, options, solver);

return new ChainingBackwardFlowFunction(options.allocationSite(), strategies, methodChains);
}
}
68 changes: 68 additions & 0 deletions idealPDS/src/main/java/typestate/ChainingForwardFlowFunction.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/**
* *****************************************************************************
* Copyright (c) 2018 Fraunhofer IEM, Paderborn, Germany
* <p>
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
* <p>
* SPDX-License-Identifier: EPL-2.0
* <p>
* Contributors:
* Johannes Spaeth - initial API and implementation
* *****************************************************************************
*/
package typestate;

import boomerang.ForwardQuery;
import boomerang.flowfunction.DefaultForwardFlowFunction;
import boomerang.scope.ControlFlowGraph;
import boomerang.scope.DeclaredMethod;
import boomerang.scope.InvokeExpr;
import boomerang.scope.Statement;
import boomerang.scope.Val;
import boomerang.solver.Strategies;
import boomerang.utils.MethodWrapper;
import java.util.Collection;
import java.util.LinkedHashSet;
import sync.pds.solver.nodes.Node;
import wpds.interfaces.State;

public class ChainingForwardFlowFunction extends DefaultForwardFlowFunction {

private final Collection<MethodWrapper> methodChains;

public ChainingForwardFlowFunction(
Strategies strategies, Collection<MethodWrapper> methodChains) {
super(strategies);

this.methodChains = methodChains;
}

@Override
public Collection<State> callToReturnFlow(
ForwardQuery query, ControlFlowGraph.Edge edge, Val fact) {
Collection<State> out = new LinkedHashSet<>(super.callToReturnFlow(query, edge, fact));

Statement statement = edge.getStart();
if (statement.isAssignStmt() && statement.containsInvokeExpr()) {
InvokeExpr invokeExpr = statement.getInvokeExpr();
DeclaredMethod declaredMethod = invokeExpr.getDeclaredMethod();

if (methodChains.contains(declaredMethod.toMethodWrapper())) {
/* If the current statement is a chained method call, consider it as an alias and
* continue the propagation with the implicitly defined local
*/
if (invokeExpr.isInstanceInvokeExpr()) {
Val base = invokeExpr.getBase();

if (base.equals(fact)) {
out.add(new Node<>(edge, statement.getLeftOp()));
}
}
}
}

return out;
}
}
26 changes: 26 additions & 0 deletions idealPDS/src/test/java/chains/Chain.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/**
* *****************************************************************************
* Copyright (c) 2018 Fraunhofer IEM, Paderborn, Germany
* <p>
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
* <p>
* SPDX-License-Identifier: EPL-2.0
* <p>
* Contributors:
* Johannes Spaeth - initial API and implementation
* *****************************************************************************
*/
package chains;

public class Chain {

public Chain chain1() {
return this;
}

public Chain chain2() {
return this;
}
}
101 changes: 101 additions & 0 deletions idealPDS/src/test/java/chains/ChainStateMachine.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
/**
* *****************************************************************************
* Copyright (c) 2018 Fraunhofer IEM, Paderborn, Germany
* <p>
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
* <p>
* SPDX-License-Identifier: EPL-2.0
* <p>
* Contributors:
* Johannes Spaeth - initial API and implementation
* *****************************************************************************
*/
package chains;

import boomerang.WeightedForwardQuery;
import boomerang.scope.ControlFlowGraph;
import java.util.Collection;
import java.util.Collections;
import typestate.TransitionFunction;
import typestate.finiteautomata.MatcherTransition;
import typestate.finiteautomata.State;
import typestate.finiteautomata.TypeStateMachineWeightFunctions;

public class ChainStateMachine extends TypeStateMachineWeightFunctions {

public enum States implements State {
INIT,
CHAIN1,
CHAIN2;

@Override
public boolean isErrorState() {
return this != CHAIN2;
}

@Override
public boolean isInitialState() {
return this == INIT;
}

@Override
public boolean isAccepting() {
return this == CHAIN2;
}
}

public ChainStateMachine() {
addTransition(
new MatcherTransition(
States.INIT,
".*chain1.*",
MatcherTransition.Parameter.This,
States.CHAIN1,
MatcherTransition.Type.OnCallToReturn));
addTransition(
new MatcherTransition(
States.CHAIN1,
".chain1.*",
MatcherTransition.Parameter.This,
States.CHAIN1,
MatcherTransition.Type.OnCallToReturn));
addTransition(
new MatcherTransition(
States.CHAIN1,
".*chain2.*",
MatcherTransition.Parameter.This,
States.CHAIN2,
MatcherTransition.Type.OnCallToReturn));
addTransition(
new MatcherTransition(
States.CHAIN2,
".chain1.*",
MatcherTransition.Parameter.This,
States.CHAIN1,
MatcherTransition.Type.OnCallToReturn));
addTransition(
new MatcherTransition(
States.CHAIN2,
".chain2.*",
MatcherTransition.Parameter.This,
States.CHAIN2,
MatcherTransition.Type.OnCallToReturn));
}

@Override
public Collection<WeightedForwardQuery<TransitionFunction>> generateSeed(
ControlFlowGraph.Edge stmt) {
try {
return generateAtAllocationSiteOf(stmt, Class.forName(Chain.class.getName()));
} catch (ClassNotFoundException e) {
return Collections.emptySet();
}
}

@Override
protected State initialState() {
return States.INIT;
}
}
29 changes: 29 additions & 0 deletions idealPDS/src/test/java/chains/ChainingTestFlowFunctionFactory.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/**
* *****************************************************************************
* Copyright (c) 2018 Fraunhofer IEM, Paderborn, Germany
* <p>
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
* <p>
* SPDX-License-Identifier: EPL-2.0
* <p>
* Contributors:
* Johannes Spaeth - initial API and implementation
* *****************************************************************************
*/
package chains;

import boomerang.utils.MethodWrapper;
import java.util.Set;
import typestate.ChainingFlowFunctionFactory;

public class ChainingTestFlowFunctionFactory extends ChainingFlowFunctionFactory {

public ChainingTestFlowFunctionFactory() {
super(
Set.of(
new MethodWrapper(Chain.class.getName(), "chain1", Chain.class.getName()),
new MethodWrapper(Chain.class.getName(), "chain2", Chain.class.getName())));
}
}
Loading