Skip to content

Commit

Permalink
Merge pull request #741 from soot-oss/fix/739_Aggregator
Browse files Browse the repository at this point in the history
Fix Aggregator, TypeAssigner, LocalNameStandardizer
  • Loading branch information
kadirayk authored Nov 9, 2023
2 parents f2e1465 + cc8a35a commit 23503d7
Show file tree
Hide file tree
Showing 28 changed files with 279 additions and 269 deletions.
9 changes: 9 additions & 0 deletions shared-test-resources/bugfixes/Issue739_Aggregator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
public class Issue739_Aggregator {
public static void main(String[] args) {
int a = Integer.valueOf(args[0]);
int b = a;
int c = b;
System.out.println(a + b + c);

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,7 @@ protected Stream<MethodSignature> resolveAllStaticInitializerCallsFromSourceMeth
classType ->
Stream.concat(
Stream.of(classType),
view.getTypeHierarchy().incompleteSuperClassesOf(classType).stream()))
view.getTypeHierarchy().superClassesOf(classType).stream()))
.filter(Objects::nonNull)
.map(classType -> view.getMethod(classType.getStaticInitializer()))
.filter(Optional::isPresent)
Expand All @@ -291,7 +291,7 @@ protected final <T extends Method> T findMethodInHierarchy(
if (optSc.isPresent()) {
SootClass<?> sc = optSc.get();

List<ClassType> superClasses = view.getTypeHierarchy().incompleteSuperClassesOf(sc.getType());
List<ClassType> superClasses = view.getTypeHierarchy().superClassesOf(sc.getType());
Set<ClassType> interfaces = view.getTypeHierarchy().implementedInterfacesOf(sc.getType());
superClasses.addAll(interfaces);

Expand Down Expand Up @@ -364,7 +364,7 @@ public CallGraph addClass(@Nonnull CallGraph oldCallGraph, @Nonnull JavaClassTyp
processWorkList(view, workList, processed, updated);

// Step 2: Add edges from old methods to methods overridden in the new class
List<ClassType> superClasses = view.getTypeHierarchy().incompleteSuperClassesOf(classType);
List<ClassType> superClasses = view.getTypeHierarchy().superClassesOf(classType);
Set<ClassType> implementedInterfaces =
view.getTypeHierarchy().implementedInterfacesOf(classType);
Stream<ClassType> superTypes =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import org.junit.Test;
import sootup.core.model.SootClass;
import sootup.core.model.SootMethod;
import sootup.core.model.SourceType;
import sootup.core.signatures.MethodSignature;
import sootup.java.bytecode.inputlocation.JavaClassPathAnalysisInputLocation;
import sootup.java.core.JavaIdentifierFactory;
Expand Down Expand Up @@ -36,7 +37,7 @@ private JavaView createViewForClassPath(String classPath, boolean useSourceCodeF
JavaProject.builder(new JavaLanguage(8))
.addInputLocation(
new JavaClassPathAnalysisInputLocation(
System.getProperty("java.home") + "/lib/rt.jar"));
System.getProperty("java.home") + "/lib/rt.jar", SourceType.Library));
if (useSourceCodeFrontend) {
javaProjectBuilder.addInputLocation(new JavaSourcePathAnalysisInputLocation(classPath));
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,10 @@ public Local getBase() {
@Override
@Nonnull
public List<Value> getUses() {
List<Value> list = new ArrayList<>();

List<? extends Value> args = getArgs();
if (args != null) {
list.addAll(args);
for (Value arg : args) {
list.addAll(arg.getUses());
}
List<Value> list = new ArrayList<>(args);
for (Value arg : args) {
list.addAll(arg.getUses());
}
list.addAll(base.getUses());
list.add(base);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,11 @@ public List<LValue> getDefs() {
public final List<Value> getUses() {
final List<Value> defsuses = getLeftOp().getUses();
final Value rightOp = getRightOp();
final List<Value> uses = rightOp.getUses();
List<Value> list = new ArrayList<>(defsuses.size() + uses.size() + 1);
final List<Value> rightOpUses = rightOp.getUses();
List<Value> list = new ArrayList<>(defsuses.size() + rightOpUses.size() + 1);
list.addAll(defsuses);
list.add(rightOp);
list.addAll(uses);
list.addAll(rightOpUses);
return list;
}

Expand Down
23 changes: 12 additions & 11 deletions sootup.core/src/main/java/sootup/core/model/Body.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,12 @@
import java.util.*;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import sootup.core.graph.*;
import sootup.core.graph.MutableBlockStmtGraph;
import sootup.core.graph.MutableStmtGraph;
import sootup.core.graph.StmtGraph;
import sootup.core.jimple.basic.*;
import sootup.core.jimple.common.ref.*;
import sootup.core.jimple.common.ref.JParameterRef;
import sootup.core.jimple.common.ref.JThisRef;
import sootup.core.jimple.common.stmt.*;
import sootup.core.signatures.MethodSignature;
import sootup.core.util.Copyable;
Expand Down Expand Up @@ -597,19 +600,17 @@ public static Map<LValue, Collection<Stmt>> collectDefs(Collection<Stmt> stmts)
* @param stmts The searched list of statements
* @return A map of Locals and their using statements
*/
public static Map<LValue, Collection<Stmt>> collectUses(Collection<Stmt> stmts) {
Map<LValue, Collection<Stmt>> allUses = new HashMap<>();
public static Map<Value, Collection<Stmt>> collectUses(Collection<Stmt> stmts) {
Map<Value, Collection<Stmt>> allUses = new HashMap<>();
for (Stmt stmt : stmts) {
Collection<Value> uses = stmt.getUses();
for (Value value : uses) {
if (value instanceof LValue) {
Collection<Stmt> localUses = allUses.get(value);
if (localUses == null) {
localUses = new ArrayList<>();
}
localUses.add(stmt);
allUses.put((LValue) value, localUses);
Collection<Stmt> localUses = allUses.get(value);
if (localUses == null) {
localUses = new ArrayList<>();
}
localUses.add(stmt);
allUses.put(value, localUses);
}
}
return allUses;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -181,8 +181,7 @@ public static boolean canDispatch(
private static List<SootClass<?>> findSuperClassesInclusive(
View<? extends SootClass<?>> view, ClassType classType) {
return Stream.concat(
Stream.of(classType),
view.getTypeHierarchy().incompleteSuperClassesOf(classType).stream())
Stream.of(classType), view.getTypeHierarchy().superClassesOf(classType).stream())
.flatMap(t -> view.getClass(t).map(Stream::of).orElseGet(Stream::empty))
.collect(Collectors.toList());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ default boolean isSubtype(@Nonnull Type supertype, @Nonnull Type potentialSubtyp
return (supertypeName.equals("java.lang.Object")
&& !potentialSubtypeName.equals("java.lang.Object"))
|| supertype.equals(superClassOf((ClassType) potentialSubtype))
|| incompleteSuperClassesOf((ClassType) potentialSubtype).contains(supertype)
|| superClassesOf((ClassType) potentialSubtype).contains(supertype)
|| implementedInterfacesOf((ClassType) potentialSubtype).contains(supertype);
} else if (potentialSubtype instanceof ArrayType) {
// Arrays are subtypes of java.lang.Object, java.io.Serializable and java.lang.Cloneable
Expand All @@ -169,27 +169,12 @@ default boolean isSubtype(@Nonnull Type supertype, @Nonnull Type potentialSubtyp
}
}

/**
* Returns all superclasses of <code>classType</code> up to <code>java.lang.Object</code>, which
* will be the last entry in the list. i.e. its ordered from bottom level to top level.
*/
@Nonnull
default List<ClassType> superClassesOf(@Nonnull ClassType classType) {
List<ClassType> superClasses = new ArrayList<>();
ClassType currentSuperClass = superClassOf(classType);
while (currentSuperClass != null) {
superClasses.add(currentSuperClass);
currentSuperClass = superClassOf(currentSuperClass);
}
return superClasses;
}

/**
* Returns all superclasses of <code>classType</code> up to <code>java.lang.Object</code>, which
* will be the last entry in the list, or till one of the superclasses is not contained in view.
*/
@Nonnull
default List<ClassType> incompleteSuperClassesOf(@Nonnull ClassType classType) {
default List<ClassType> superClassesOf(@Nonnull ClassType classType) {
List<ClassType> superClasses = new ArrayList<>();
ClassType currentSuperClass = null;
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@
import javax.annotation.Nullable;
import org.jgrapht.Graph;
import org.jgrapht.graph.SimpleDirectedGraph;
import sootup.core.frontend.ResolveException;
import sootup.core.model.SootClass;
import sootup.core.typehierarchy.ViewTypeHierarchy.ScanResult.Edge;
import sootup.core.typehierarchy.ViewTypeHierarchy.ScanResult.EdgeType;
Expand Down Expand Up @@ -67,10 +66,10 @@ public ViewTypeHierarchy(@Nonnull View<? extends SootClass<?>> view) {
public Set<ClassType> implementersOf(@Nonnull ClassType interfaceType) {
Vertex vertex = lazyScanResult.get().typeToVertex.get(interfaceType);
if (vertex == null) {
throw new ResolveException("Could not find " + interfaceType + " in hierarchy.");
throw new IllegalArgumentException("Could not find '" + interfaceType + "' in hierarchy.");
}
if (vertex.type != VertexType.Interface) {
throw new IllegalArgumentException(interfaceType + " is not an interface.");
throw new IllegalArgumentException("'" + interfaceType + "' is not an interface.");
}
return subtypesOf(interfaceType);
}
Expand All @@ -80,10 +79,10 @@ public Set<ClassType> implementersOf(@Nonnull ClassType interfaceType) {
public Set<ClassType> subclassesOf(@Nonnull ClassType classType) {
Vertex vertex = lazyScanResult.get().typeToVertex.get(classType);
if (vertex == null) {
throw new ResolveException("Could not find " + classType + " in hierarchy.");
throw new IllegalArgumentException("Could not find '" + classType + "' in hierarchy.");
}
if (vertex.type != VertexType.Class) {
throw new IllegalArgumentException(classType + " is not a class.");
throw new IllegalArgumentException("'" + classType + "' is not a class.");
}
return subtypesOf(classType);
}
Expand All @@ -94,7 +93,7 @@ public Set<ClassType> subtypesOf(@Nonnull ClassType type) {
ScanResult scanResult = lazyScanResult.get();
Vertex vertex = scanResult.typeToVertex.get(type);
if (vertex == null) {
throw new ResolveException("Could not find " + type + " in hierarchy.");
throw new IllegalArgumentException("Could not find '" + type + "' in hierarchy.");
}

Set<ClassType> subclasses = new HashSet<>();
Expand All @@ -110,7 +109,7 @@ public Set<ClassType> directSubtypesOf(@Nonnull ClassType type) {
ScanResult scanResult = lazyScanResult.get();
Vertex vertex = scanResult.typeToVertex.get(type);
if (vertex == null) {
throw new ResolveException("Could not find " + type + " in hierarchy.");
throw new IllegalArgumentException("Could not find '" + type + "' in hierarchy.");
}

Set<ClassType> subclasses = new HashSet<>();
Expand Down Expand Up @@ -141,7 +140,7 @@ public Set<ClassType> directSubtypesOf(@Nonnull ClassType type) {
}

@Nonnull
public List<Vertex> superClassesOf(@Nonnull Vertex classVertex, boolean includingSelf) {
protected List<Vertex> superClassesOf(@Nonnull Vertex classVertex, boolean includingSelf) {
ScanResult scanResult = lazyScanResult.get();
Graph<Vertex, Edge> graph = scanResult.graph;

Expand All @@ -167,21 +166,21 @@ public List<Vertex> superClassesOf(@Nonnull Vertex classVertex, boolean includin
return superClasses;
}

public Stream<Vertex> directlyImplementedInterfacesOf(@Nonnull Vertex classVertex) {
protected Stream<Vertex> directlyImplementedInterfacesOf(@Nonnull Vertex classVertex) {
Graph<Vertex, Edge> graph = lazyScanResult.get().graph;
return graph.outgoingEdgesOf(classVertex).stream()
.filter(edge -> edge.type == EdgeType.ClassDirectlyImplements)
.map(graph::getEdgeTarget);
}

public Stream<Vertex> directlyExtendedInterfacesOf(@Nonnull Vertex interfaceVertex) {
protected Stream<Vertex> directlyExtendedInterfacesOf(@Nonnull Vertex interfaceVertex) {
Graph<Vertex, Edge> graph = lazyScanResult.get().graph;
return graph.outgoingEdgesOf(interfaceVertex).stream()
.filter(edge -> edge.type == EdgeType.InterfaceDirectlyExtends)
.map(graph::getEdgeTarget);
}

public Stream<Vertex> directSuperClassOf(@Nonnull Vertex classVertex) {
protected Stream<Vertex> directSuperClassOf(@Nonnull Vertex classVertex) {
Graph<Vertex, Edge> graph = lazyScanResult.get().graph;
return graph.outgoingEdgesOf(classVertex).stream()
.filter(edge -> edge.type == EdgeType.ClassDirectlyExtends)
Expand All @@ -191,7 +190,7 @@ public Stream<Vertex> directSuperClassOf(@Nonnull Vertex classVertex) {
public Set<ClassType> directlyImplementedInterfacesOf(@Nonnull ClassType classType) {
Vertex vertex = lazyScanResult.get().typeToVertex.get(classType);
if (vertex == null) {
throw new IllegalStateException("Could not find '" + classType + "' in hierarchy.");
throw new IllegalArgumentException("Could not find '" + classType + "' in hierarchy.");
}
if (vertex.type != VertexType.Class) {
throw new IllegalArgumentException(classType + " is not a class.");
Expand All @@ -205,7 +204,7 @@ public Set<ClassType> directlyImplementedInterfacesOf(@Nonnull ClassType classTy
public Set<ClassType> directlyExtendedInterfacesOf(@Nonnull ClassType interfaceType) {
Vertex vertex = lazyScanResult.get().typeToVertex.get(interfaceType);
if (vertex == null) {
throw new IllegalStateException("Could not find " + interfaceType + " in hierarchy.");
throw new IllegalArgumentException("Could not find " + interfaceType + " in hierarchy.");
}
if (vertex.type != VertexType.Interface) {
throw new IllegalArgumentException(interfaceType + " is not a class.");
Expand All @@ -229,7 +228,7 @@ public boolean contains(ClassType type) {
public ClassType directSuperClassOf(@Nonnull ClassType classType) {
Vertex vertex = lazyScanResult.get().typeToVertex.get(classType);
if (vertex == null) {
throw new IllegalStateException("Could not find " + classType + " in hierarchy.");
throw new IllegalArgumentException("Could not find " + classType + " in hierarchy.");
}
Graph<Vertex, Edge> graph = lazyScanResult.get().graph;
List<Vertex> list =
Expand All @@ -242,7 +241,7 @@ public ClassType directSuperClassOf(@Nonnull ClassType classType) {
/* is java.lang.Object */
return null;
} else if (list.size() > 1) {
throw new RuntimeException(classType + "cannot have multiple superclasses");
throw new IllegalArgumentException(classType + "cannot have multiple superclasses");
} else {
return list.get(0).javaClassType;
}
Expand All @@ -255,7 +254,8 @@ public Set<ClassType> implementedInterfacesOf(@Nonnull ClassType type) {
Vertex vertex = scanResult.typeToVertex.get(type);

if (vertex == null) {
throw new IllegalStateException("Could not find " + type + " in hierarchy for view " + view);
throw new IllegalArgumentException(
"Could not find " + type + " in hierarchy for view " + view);
}

switch (vertex.type) {
Expand Down Expand Up @@ -299,21 +299,25 @@ private Stream<ClassType> selfAndImplementedInterfaces(Vertex vertex) {
@Nullable
@Override
public ClassType superClassOf(@Nonnull ClassType classType) {
return sootClassFor(classType).getSuperclass().orElse(null);
final Optional<? extends SootClass<?>> classOpt = view.getClass(classType);
if (!classOpt.isPresent()) {
throw new IllegalArgumentException("Could not find '" + classType + "' in the view.");
}
return classOpt.get().getSuperclass().orElse(null);
}

public boolean isInterface(@Nonnull ClassType type) {
Vertex vertex = lazyScanResult.get().typeToVertex.get(type);
if (vertex == null) {
throw new RuntimeException("Could not find " + type + " in hierarchy.");
throw new IllegalArgumentException("Could not find '" + type + "' in hierarchy.");
}
return vertex.type == VertexType.Interface;
}

public boolean isClass(@Nonnull ClassType type) {
Vertex vertex = lazyScanResult.get().typeToVertex.get(type);
if (vertex == null) {
throw new RuntimeException("Could not find " + type + " in hierarchy.");
throw new IllegalArgumentException("Could not find '" + type + "' in hierarchy.");
}
return vertex.type == VertexType.Class;
}
Expand Down Expand Up @@ -416,19 +420,14 @@ private static Vertex createAndAddInterfaceVertex(Graph<Vertex, Edge> graph, Cla
return interfaceVertex;
}

@Nonnull
private SootClass<?> sootClassFor(@Nonnull ClassType classType) {
return view.getClassOrThrow(classType);
}

@Override
public void addType(@Nonnull SootClass<?> sootClass) {
ScanResult scanResult = lazyScanResult.get();
addSootClassToGraph(sootClass, scanResult.typeToVertex, scanResult.graph);
}

/** Holds a vertex for each {@link ClassType} encountered during the scan. */
static class ScanResult {
protected static class ScanResult {

enum VertexType {
Class,
Expand All @@ -439,7 +438,7 @@ enum VertexType {
* @see #javaClassType
* @see #type
*/
static class Vertex {
protected static class Vertex {
@Nonnull final ClassType javaClassType;
@Nonnull final VertexType type;

Expand All @@ -449,7 +448,7 @@ static class Vertex {
}
}

enum EdgeType {
protected enum EdgeType {
/** Edge to an interface vertex this interface extends directly, non-transitively. */
InterfaceDirectlyExtends,
/** Edge to an interface extending this interface directly, non-transitively. */
Expand All @@ -459,7 +458,7 @@ enum EdgeType {
}

/** @see #type */
static class Edge {
protected static class Edge {
@Nonnull final EdgeType type;

Edge(@Nonnull EdgeType type) {
Expand Down
Loading

0 comments on commit 23503d7

Please sign in to comment.