From 291fb11c484dd5f0855d6ace3ace986ea9a1b9fc Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Thu, 11 Oct 2018 15:03:51 +0200 Subject: [PATCH] Java: Autoformat semmle.code.java.dispatch. --- .../code/java/dispatch/DispatchFlow.qll | 106 +++++++++------ .../code/java/dispatch/VirtualDispatch.qll | 121 +++++++++++------- .../code/java/dispatch/WrappedInvocation.qll | 10 +- 3 files changed, 146 insertions(+), 91 deletions(-) diff --git a/java/ql/src/semmle/code/java/dispatch/DispatchFlow.qll b/java/ql/src/semmle/code/java/dispatch/DispatchFlow.qll index d1d1fff3979..1cd6a18bc89 100644 --- a/java/ql/src/semmle/code/java/dispatch/DispatchFlow.qll +++ b/java/ql/src/semmle/code/java/dispatch/DispatchFlow.qll @@ -9,12 +9,11 @@ private import semmle.code.java.Maps /** * Gets a viable dispatch target for `ma`. This is the input dispatch relation. */ -private Method viableImpl_inp(MethodAccess ma) { - result = viableImpl_v2(ma) -} +private Method viableImpl_inp(MethodAccess ma) { result = viableImpl_v2(ma) } private Callable dispatchCand(Call c) { - c instanceof ConstructorCall and result = c.getCallee().getSourceDeclaration() or + c instanceof ConstructorCall and result = c.getCallee().getSourceDeclaration() + or result = viableImpl_inp(c) } @@ -97,18 +96,23 @@ private predicate dispatchOrigin(ClassInstanceExpr cie, MethodAccess ma, Method /** Holds if `t` is a type that is relevant for dispatch flow. */ private predicate relevant(RefType t) { - exists(ClassInstanceExpr cie | dispatchOrigin(cie, _, _) and t = cie.getConstructedType().getSourceDeclaration()) or - relevant(t.getErasure()) or - exists(RefType r | relevant(r) and t = r.getASourceSupertype()) or - relevant(t.(Array).getComponentType()) or - t instanceof MapType or + exists(ClassInstanceExpr cie | + dispatchOrigin(cie, _, _) and t = cie.getConstructedType().getSourceDeclaration() + ) + or + relevant(t.getErasure()) + or + exists(RefType r | relevant(r) and t = r.getASourceSupertype()) + or + relevant(t.(Array).getComponentType()) + or + t instanceof MapType + or t instanceof CollectionType } /** A node with a type that is relevant for dispatch flow. */ -private class RelevantNode extends Node { - RelevantNode() { relevant(this.getType()) } -} +private class RelevantNode extends Node { RelevantNode() { relevant(this.getType()) } } /** * Holds if `p` is the `i`th parameter of a viable dispatch target of `call`. @@ -141,7 +145,8 @@ private predicate callFlowStepCand(RelevantNode n1, RelevantNode n2) { ret.getEnclosingCallable() = m and ret.getResult() = n1.asExpr() and m = dispatchCand(n2.asExpr()) - ) or + ) + or viableArgParamCand(n1, n2) } @@ -151,47 +156,66 @@ private predicate callFlowStepCand(RelevantNode n1, RelevantNode n2) { */ private predicate flowStep(RelevantNode n1, RelevantNode n2) { exists(BaseSsaVariable v, BaseSsaVariable def | - def.(BaseSsaUpdate).getDefiningExpr().(VariableAssign).getSource() = n1.asExpr() or - def.(BaseSsaImplicitInit).isParameterDefinition(n1.asParameter()) or + def.(BaseSsaUpdate).getDefiningExpr().(VariableAssign).getSource() = n1.asExpr() + or + def.(BaseSsaImplicitInit).isParameterDefinition(n1.asParameter()) + or exists(EnhancedForStmt for | for.getVariable() = def.(BaseSsaUpdate).getDefiningExpr() and for.getExpr() = n1.asExpr() and n1.getType() instanceof Array ) - | + | v.getAnUltimateDefinition() = def and v.getAUse() = n2.asExpr() - ) or - exists(Callable c | - n1.(InstanceParameterNode).getCallable() = c - | - exists(InstanceAccess ia | ia = n2.asExpr() and ia.getEnclosingCallable() = c and ia.isOwnInstanceAccess()) or + ) + or + exists(Callable c | n1.(InstanceParameterNode).getCallable() = c | + exists(InstanceAccess ia | + ia = n2.asExpr() and ia.getEnclosingCallable() = c and ia.isOwnInstanceAccess() + ) + or n2.(ImplicitInstanceAccess).getInstanceAccess().(OwnInstanceAccess).getEnclosingCallable() = c - ) or + ) + or exists(Field f | f.getAnAssignedValue() = n1.asExpr() and n2.asExpr().(FieldRead).getField() = f - ) or + ) + or exists(EnumType enum, Method getValue | enum.getAnEnumConstant().getAnAssignedValue() = n1.asExpr() and getValue.getDeclaringType() = enum and (getValue.hasName("values") or getValue.hasName("valueOf")) and n2.asExpr().(MethodAccess).getMethod() = getValue - ) or - n2.asExpr().(ParExpr).getExpr() = n1.asExpr() or - n2.asExpr().(CastExpr).getExpr() = n1.asExpr() or - n2.asExpr().(ConditionalExpr).getTrueExpr() = n1.asExpr() or - n2.asExpr().(ConditionalExpr).getFalseExpr() = n1.asExpr() or - n2.asExpr().(AssignExpr).getSource() = n1.asExpr() or - n2.asExpr().(ArrayInit).getAnInit() = n1.asExpr() or - n2.asExpr().(ArrayCreationExpr).getInit() = n1.asExpr() or - n2.asExpr().(ArrayAccess).getArray() = n1.asExpr() or - exists(Argument arg | n1.asExpr() = arg and arg.isVararg() and n2.(ImplicitVarargsArray).getCall() = arg.getCall()) or + ) + or + n2.asExpr().(ParExpr).getExpr() = n1.asExpr() + or + n2.asExpr().(CastExpr).getExpr() = n1.asExpr() + or + n2.asExpr().(ConditionalExpr).getTrueExpr() = n1.asExpr() + or + n2.asExpr().(ConditionalExpr).getFalseExpr() = n1.asExpr() + or + n2.asExpr().(AssignExpr).getSource() = n1.asExpr() + or + n2.asExpr().(ArrayInit).getAnInit() = n1.asExpr() + or + n2.asExpr().(ArrayCreationExpr).getInit() = n1.asExpr() + or + n2.asExpr().(ArrayAccess).getArray() = n1.asExpr() + or + exists(Argument arg | + n1.asExpr() = arg and arg.isVararg() and n2.(ImplicitVarargsArray).getCall() = arg.getCall() + ) + or exists(AssignExpr a, Variable v | a.getSource() = n1.asExpr() and a.getDest().(ArrayAccess).getArray() = v.getAnAccess() and n2.asExpr() = v.getAnAccess().(RValue) - ) or + ) + or exists(Variable v, MethodAccess put, MethodAccess get | put.getArgument(1) = n1.asExpr() and put.getMethod().(MapMethod).hasName("put") and @@ -199,17 +223,19 @@ private predicate flowStep(RelevantNode n1, RelevantNode n2) { get.getQualifier() = v.getAnAccess() and get.getMethod().(MapMethod).hasName("get") and n2.asExpr() = get - ) or + ) + or exists(Variable v, MethodAccess add | add.getAnArgument() = n1.asExpr() and add.getMethod().(CollectionMethod).hasName("add") and add.getQualifier() = v.getAnAccess() - | + | exists(MethodAccess get | get.getQualifier() = v.getAnAccess() and get.getMethod().(CollectionMethod).hasName("get") and n2.asExpr() = get - ) or + ) + or exists(EnhancedForStmt for, BaseSsaVariable ssa, BaseSsaVariable def | for.getVariable() = def.(BaseSsaUpdate).getDefiningExpr() and for.getExpr() = v.getAnAccess() and @@ -223,7 +249,8 @@ private predicate flowStep(RelevantNode n1, RelevantNode n2) { * Holds if `n` is forward-reachable from a relevant `ClassInstanceExpr`. */ private predicate nodeCandFwd(Node n) { - dispatchOrigin(n.asExpr(), _, _) or + dispatchOrigin(n.asExpr(), _, _) + or exists(Node mid | nodeCandFwd(mid) | flowStep(mid, n) or callFlowStepCand(mid, n)) } @@ -236,7 +263,8 @@ private predicate nodeCand(Node n) { dispatchOrigin(_, ma, _) and n = getInstanceArgument(ma) and nodeCandFwd(n) - ) or + ) + or exists(Node mid | nodeCand(mid) | flowStep(n, mid) or callFlowStepCand(n, mid)) and nodeCandFwd(n) } diff --git a/java/ql/src/semmle/code/java/dispatch/VirtualDispatch.qll b/java/ql/src/semmle/code/java/dispatch/VirtualDispatch.qll index 509b97ac8ec..38984efe50d 100644 --- a/java/ql/src/semmle/code/java/dispatch/VirtualDispatch.qll +++ b/java/ql/src/semmle/code/java/dispatch/VirtualDispatch.qll @@ -24,12 +24,11 @@ Callable exactCallable(Call c) { c instanceof ConstructorCall and result = c.getCallee() } -private predicate implCount(MethodAccess m, int c) { - strictcount(viableImpl(m)) = c -} +private predicate implCount(MethodAccess m, int c) { strictcount(viableImpl(m)) = c } Callable viableCallable(Call c) { - result = viableImpl(c) or + result = viableImpl(c) + or c instanceof ConstructorCall and result = c.getCallee().getSourceDeclaration() } @@ -38,11 +37,11 @@ class CalledMethod extends Method { CalledMethod() { exists(MethodAccess ma | ma.getMethod() = this) } } -cached private module Dispatch { +cached +private module Dispatch { /** Gets a viable implementation of the method called in the given method access. */ - cached Method viableImpl(MethodAccess ma) { - result = DispatchFlow::viableImpl_out(ma) - } + cached + Method viableImpl(MethodAccess ma) { result = DispatchFlow::viableImpl_out(ma) } private predicate qualType(VirtualMethodAccess ma, RefType t, boolean exact) { exprTypeFlow(ma.getQualifier(), t, exact) @@ -53,13 +52,14 @@ cached private module Dispatch { * * Gets a viable implementation of the method called in the given method access. */ - cached Method viableImpl_v2(MethodAccess ma) { + cached + Method viableImpl_v2(MethodAccess ma) { result = viableImpl_v1(ma) and ( exists(Method def, RefType t, boolean exact | qualType(ma, t, exact) and def = ma.getMethod() - | + | exact = true and result = exactMethodImpl(def, t.getSourceDeclaration()) or exact = false and @@ -67,7 +67,8 @@ cached private module Dispatch { result = viableMethodImpl(def, t.getSourceDeclaration(), t2) and not Unification_v2::failsUnification(t, t2) ) - ) or + ) + or not qualType(ma, _, _) ) } @@ -84,12 +85,14 @@ cached private module Dispatch { } private predicate unificationTargets(Type t1, Type t2) { - exists(GenericType g | unificationTargetLeft(t1, g) and unificationTargetRight(t2, g)) or + exists(GenericType g | unificationTargetLeft(t1, g) and unificationTargetRight(t2, g)) + or exists(Array a1, Array a2 | unificationTargets(a1, a2) and t1 = a1.getComponentType() and t2 = a2.getComponentType() - ) or + ) + or exists(ParameterizedType pt1, ParameterizedType pt2, int pos | unificationTargets(pt1, pt2) and not pt1.getSourceDeclaration() != pt2.getSourceDeclaration() and @@ -99,7 +102,9 @@ cached private module Dispatch { } pragma[noinline] - private predicate typeArgsOfUnificationTargets(ParameterizedType t1, ParameterizedType t2, int pos, RefType arg1, RefType arg2) { + private predicate typeArgsOfUnificationTargets( + ParameterizedType t1, ParameterizedType t2, int pos, RefType arg1, RefType arg2 + ) { unificationTargets(t1, t2) and arg1 = t1.getTypeArgument(pos) and arg2 = t2.getTypeArgument(pos) @@ -111,14 +116,21 @@ cached private module Dispatch { exists(RefType arg1, RefType arg2 | typeArgsOfUnificationTargets(t1, t2, _, arg1, arg2) and failsUnification(arg1, arg2) - ) or - failsUnification(t1.(Array).getComponentType(), t2.(Array).getComponentType()) or + ) + or + failsUnification(t1.(Array).getComponentType(), t2.(Array).getComponentType()) + or not ( - t1 instanceof Array and t2 instanceof Array or - t1.(PrimitiveType) = t2.(PrimitiveType) or - t1.(Class).getSourceDeclaration() = t2.(Class).getSourceDeclaration() or - t1.(Interface).getSourceDeclaration() = t2.(Interface).getSourceDeclaration() or - t1 instanceof BoundedType and t2 instanceof RefType or + t1 instanceof Array and t2 instanceof Array + or + t1.(PrimitiveType) = t2.(PrimitiveType) + or + t1.(Class).getSourceDeclaration() = t2.(Class).getSourceDeclaration() + or + t1.(Interface).getSourceDeclaration() = t2.(Interface).getSourceDeclaration() + or + t1 instanceof BoundedType and t2 instanceof RefType + or t1 instanceof RefType and t2 instanceof BoundedType ) ) @@ -156,11 +168,12 @@ cached private module Dispatch { */ private Method viableImpl_v1_cand(MethodAccess source) { not result.isAbstract() and - if source instanceof VirtualMethodAccess then + if source instanceof VirtualMethodAccess + then exists(CalledMethod def, RefType t, boolean exact | source.getMethod() = def and hasQualifierType(source, t, exact) - | + | exact = true and result = exactMethodImpl(def, t.getSourceDeclaration()) or exact = false and @@ -169,8 +182,7 @@ cached private module Dispatch { not Unification_v1::failsUnification(t, t2) ) ) - else - result = source.getMethod().getSourceDeclaration() + else result = source.getMethod().getSourceDeclaration() } private module Unification_v1 { @@ -185,12 +197,14 @@ cached private module Dispatch { } private predicate unificationTargets(Type t1, Type t2) { - exists(GenericType g | unificationTargetLeft(t1, g) and unificationTargetRight(t2, g)) or + exists(GenericType g | unificationTargetLeft(t1, g) and unificationTargetRight(t2, g)) + or exists(Array a1, Array a2 | unificationTargets(a1, a2) and t1 = a1.getComponentType() and t2 = a2.getComponentType() - ) or + ) + or exists(ParameterizedType pt1, ParameterizedType pt2, int pos | unificationTargets(pt1, pt2) and not pt1.getSourceDeclaration() != pt2.getSourceDeclaration() and @@ -200,7 +214,9 @@ cached private module Dispatch { } pragma[noinline] - private predicate typeArgsOfUnificationTargets(ParameterizedType t1, ParameterizedType t2, int pos, RefType arg1, RefType arg2) { + private predicate typeArgsOfUnificationTargets( + ParameterizedType t1, ParameterizedType t2, int pos, RefType arg1, RefType arg2 + ) { unificationTargets(t1, t2) and arg1 = t1.getTypeArgument(pos) and arg2 = t2.getTypeArgument(pos) @@ -212,14 +228,21 @@ cached private module Dispatch { exists(RefType arg1, RefType arg2 | typeArgsOfUnificationTargets(t1, t2, _, arg1, arg2) and failsUnification(arg1, arg2) - ) or - failsUnification(t1.(Array).getComponentType(), t2.(Array).getComponentType()) or + ) + or + failsUnification(t1.(Array).getComponentType(), t2.(Array).getComponentType()) + or not ( - t1 instanceof Array and t2 instanceof Array or - t1.(PrimitiveType) = t2.(PrimitiveType) or - t1.(Class).getSourceDeclaration() = t2.(Class).getSourceDeclaration() or - t1.(Interface).getSourceDeclaration() = t2.(Interface).getSourceDeclaration() or - t1 instanceof BoundedType and t2 instanceof RefType or + t1 instanceof Array and t2 instanceof Array + or + t1.(PrimitiveType) = t2.(PrimitiveType) + or + t1.(Class).getSourceDeclaration() = t2.(Class).getSourceDeclaration() + or + t1.(Interface).getSourceDeclaration() = t2.(Interface).getSourceDeclaration() + or + t1 instanceof BoundedType and t2 instanceof RefType + or t1 instanceof RefType and t2 instanceof BoundedType ) ) @@ -227,7 +250,8 @@ cached private module Dispatch { } private RefType getPreciseType(Expr e) { - result = e.(FunctionalExpr).getConstructedType() or + result = e.(FunctionalExpr).getConstructedType() + or not e instanceof FunctionalExpr and result = e.getType() } @@ -237,20 +261,25 @@ cached private module Dispatch { // and take the type of the assigned value. exists(RefType srctype | srctype = getPreciseType(src) | exists(BoundedType bd | bd = srctype | - t = bd.getAnUltimateUpperBoundType() or + t = bd.getAnUltimateUpperBoundType() + or not exists(bd.getAnUltimateUpperBoundType()) and t = ma.getMethod().getDeclaringType() - ) or + ) + or t = srctype and not srctype instanceof BoundedType ) and // If we have a class instance expression, then we know the exact type. // This is an important improvement in precision. if src instanceof ClassInstanceExpr then exact = true else exact = false - ) or + ) + or // If the call has no qualifier then it's an implicit `this` qualifier, // so start from the caller's declaring type or enclosing type. - not exists(ma.getQualifier()) and exact = false and + not exists(ma.getQualifier()) and + exact = false and ( - ma.isOwnMethodAccess() and t = ma.getEnclosingCallable().getDeclaringType() or + ma.isOwnMethodAccess() and t = ma.getEnclosingCallable().getDeclaringType() + or ma.isEnclosingMethodAccess(t) ) } @@ -274,9 +303,7 @@ cached private module Dispatch { pragma[noinline] private predicate hasSrcMethod(SrcRefType t, Method impl) { - exists(Method m | - t.hasMethod(m, _, _) and impl = m.getSourceDeclaration() - ) + exists(Method m | t.hasMethod(m, _, _) and impl = m.getSourceDeclaration()) } private predicate hasViableSubtype(RefType t, SrcRefType sub) { @@ -284,7 +311,6 @@ cached private module Dispatch { not sub instanceof Interface and not sub.isAbstract() } - } import Dispatch @@ -294,7 +320,7 @@ private Expr variableTrackStep(Expr use) { use.getType() instanceof RefType and not result instanceof NullLiteral and not v.(LocalVariableDecl).getDeclExpr().hasImplicitInit() - | + | not v instanceof Parameter and result = v.getAnAssignedValue() or @@ -314,6 +340,7 @@ private Expr variableTrackPath(Expr use) { * Gets an expression by tracking `use` backwards through variable assignments. */ Expr variableTrack(Expr use) { - result = variableTrackPath(use) or + result = variableTrackPath(use) + or not exists(variableTrackPath(use)) and result = use } diff --git a/java/ql/src/semmle/code/java/dispatch/WrappedInvocation.qll b/java/ql/src/semmle/code/java/dispatch/WrappedInvocation.qll index 8704bcf316e..c80efdcc65c 100644 --- a/java/ql/src/semmle/code/java/dispatch/WrappedInvocation.qll +++ b/java/ql/src/semmle/code/java/dispatch/WrappedInvocation.qll @@ -29,9 +29,7 @@ class FunctionalInterface extends Interface { } /** Gets the single method of this interface. */ - Method getRunMethod() { - getAPotentialRunMethod(this).getSourceDeclaration() = result - } + Method getRunMethod() { getAPotentialRunMethod(this).getSourceDeclaration() = result } } /** @@ -41,7 +39,8 @@ class FunctionalInterface extends Interface { private predicate runner(Method m, int n, Method runmethod) { m.getParameterType(n).(RefType).getSourceDeclaration().(FunctionalInterface).getRunMethod() = runmethod and ( - m.isNative() or + m.isNative() + or exists(Parameter p, MethodAccess ma, int j | p = m.getParameter(n) and ma.getEnclosingCallable() = m and @@ -63,7 +62,8 @@ private Expr getRunnerArgument(MethodAccess ma, Method runmethod) { result = ma.getArgument(param) ) or - getRunnerArgument(ma, runmethod).(CastExpr).getExpr() = result or + getRunnerArgument(ma, runmethod).(CastExpr).getExpr() = result + or getRunnerArgument(ma, runmethod).(VarAccess).getVariable().getAnAssignedValue() = result }