Skip to content

Commit 5cd03b4

Browse files
committed
Guards: Remove CustomGuard nesting in Guards instantiation.
1 parent 621b483 commit 5cd03b4

File tree

2 files changed

+110
-100
lines changed

2 files changed

+110
-100
lines changed

java/ql/lib/semmle/code/java/controlflow/Guards.qll

Lines changed: 60 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,58 @@ private module GuardsInput implements SharedGuards::InputSig<Location> {
322322

323323
Expr getElse() { result = super.getFalseExpr() }
324324
}
325+
326+
class Parameter = J::Parameter;
327+
328+
private int parameterPosition() { result in [-1, any(Parameter p).getPosition()] }
329+
330+
/** A parameter position represented by an integer. */
331+
class ParameterPosition extends int {
332+
ParameterPosition() { this = parameterPosition() }
333+
}
334+
335+
/** An argument position represented by an integer. */
336+
class ArgumentPosition extends int {
337+
ArgumentPosition() { this = parameterPosition() }
338+
}
339+
340+
/** Holds if arguments at position `apos` match parameters at position `ppos`. */
341+
overlay[caller?]
342+
pragma[inline]
343+
predicate parameterMatch(ParameterPosition ppos, ArgumentPosition apos) { ppos = apos }
344+
345+
final private class FinalMethod = Method;
346+
347+
class BooleanMethod extends FinalMethod {
348+
BooleanMethod() {
349+
super.getReturnType().(PrimitiveType).hasName("boolean") and
350+
not super.isOverridable()
351+
}
352+
353+
Parameter getParameter(ParameterPosition ppos) {
354+
super.getParameter(ppos) = result and
355+
not result.isVarargs()
356+
}
357+
358+
GuardsInput::Expr getAReturnExpr() {
359+
exists(ReturnStmt ret |
360+
this = ret.getEnclosingCallable() and
361+
ret.getResult() = result
362+
)
363+
}
364+
}
365+
366+
private predicate booleanMethodCall(MethodCall call, BooleanMethod m) {
367+
call.getMethod().getSourceDeclaration() = m
368+
}
369+
370+
class BooleanMethodCall extends GuardsInput::Expr instanceof MethodCall {
371+
BooleanMethodCall() { booleanMethodCall(this, _) }
372+
373+
BooleanMethod getMethod() { booleanMethodCall(this, result) }
374+
375+
GuardsInput::Expr getArgument(ArgumentPosition apos) { result = super.getArgument(apos) }
376+
}
325377
}
326378

327379
private module GuardsImpl = SharedGuards::Make<Location, GuardsInput>;
@@ -364,6 +416,10 @@ private module LogicInput_v1 implements GuardsImpl::LogicInputSig {
364416
}
365417
}
366418

419+
predicate parameterDefinition(Parameter p, SsaDefinition def) {
420+
def.(BaseSsaImplicitInit).isParameterDefinition(p)
421+
}
422+
367423
predicate additionalNullCheck = LogicInputCommon::additionalNullCheck/4;
368424

369425
predicate additionalImpliesStep(
@@ -400,14 +456,16 @@ private module LogicInput_v2 implements GuardsImpl::LogicInputSig {
400456
}
401457
}
402458

459+
predicate parameterDefinition(Parameter p, SsaDefinition def) {
460+
def.(SSA::SsaImplicitInit).isParameterDefinition(p)
461+
}
462+
403463
predicate additionalNullCheck = LogicInputCommon::additionalNullCheck/4;
404464

405465
predicate additionalImpliesStep(
406466
GuardsImpl::PreGuard g1, GuardValue v1, GuardsImpl::PreGuard g2, GuardValue v2
407467
) {
408468
LogicInput_v1::additionalImpliesStep(g1, v1, g2, v2)
409-
or
410-
CustomGuard::additionalImpliesStep(g1, v1, g2, v2)
411469
}
412470
}
413471

@@ -424,67 +482,8 @@ private module LogicInput_v3 implements GuardsImpl::LogicInputSig {
424482
predicate additionalImpliesStep = LogicInput_v2::additionalImpliesStep/4;
425483
}
426484

427-
private module CustomGuardInput implements Guards_v2::CustomGuardInputSig {
428-
private import semmle.code.java.dataflow.SSA
429-
430-
private int parameterPosition() { result in [-1, any(Parameter p).getPosition()] }
431-
432-
/** A parameter position represented by an integer. */
433-
class ParameterPosition extends int {
434-
ParameterPosition() { this = parameterPosition() }
435-
}
436-
437-
/** An argument position represented by an integer. */
438-
class ArgumentPosition extends int {
439-
ArgumentPosition() { this = parameterPosition() }
440-
}
441-
442-
/** Holds if arguments at position `apos` match parameters at position `ppos`. */
443-
overlay[caller?]
444-
pragma[inline]
445-
predicate parameterMatch(ParameterPosition ppos, ArgumentPosition apos) { ppos = apos }
446-
447-
final private class FinalMethod = Method;
448-
449-
class BooleanMethod extends FinalMethod {
450-
BooleanMethod() {
451-
super.getReturnType().(PrimitiveType).hasName("boolean") and
452-
not super.isOverridable()
453-
}
454-
455-
LogicInput_v2::SsaDefinition getParameter(ParameterPosition ppos) {
456-
exists(Parameter p |
457-
super.getParameter(ppos) = p and
458-
not p.isVarargs() and
459-
result.(SsaImplicitInit).isParameterDefinition(p)
460-
)
461-
}
462-
463-
GuardsInput::Expr getAReturnExpr() {
464-
exists(ReturnStmt ret |
465-
this = ret.getEnclosingCallable() and
466-
ret.getResult() = result
467-
)
468-
}
469-
}
470-
471-
private predicate booleanMethodCall(MethodCall call, BooleanMethod m) {
472-
call.getMethod().getSourceDeclaration() = m
473-
}
474-
475-
class BooleanMethodCall extends GuardsInput::Expr instanceof MethodCall {
476-
BooleanMethodCall() { booleanMethodCall(this, _) }
477-
478-
BooleanMethod getMethod() { booleanMethodCall(this, result) }
479-
480-
GuardsInput::Expr getArgument(ArgumentPosition apos) { result = super.getArgument(apos) }
481-
}
482-
}
483-
484485
class GuardValue = GuardsImpl::GuardValue;
485486

486-
private module CustomGuard = Guards_v2::CustomGuard<CustomGuardInput>;
487-
488487
/** INTERNAL: Don't use. */
489488
module Guards_v1 = GuardsImpl::Logic<LogicInput_v1>;
490489

shared/controlflow/codeql/controlflow/Guards.qll

Lines changed: 50 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,46 @@ signature module InputSig<LocationSig Location> {
207207
/** Gets the false branch of this expression. */
208208
Expr getElse();
209209
}
210+
211+
class Parameter {
212+
/** Gets a textual representation of this parameter. */
213+
string toString();
214+
215+
/** Gets the location of this parameter. */
216+
Location getLocation();
217+
}
218+
219+
class ParameterPosition {
220+
/** Gets a textual representation of this element. */
221+
bindingset[this]
222+
string toString();
223+
}
224+
225+
class ArgumentPosition {
226+
/** Gets a textual representation of this element. */
227+
bindingset[this]
228+
string toString();
229+
}
230+
231+
/**
232+
* Holds if the parameter position `ppos` matches the argument position
233+
* `apos`.
234+
*/
235+
predicate parameterMatch(ParameterPosition ppos, ArgumentPosition apos);
236+
237+
/** A non-overridable method with a boolean return value. */
238+
class BooleanMethod {
239+
Parameter getParameter(ParameterPosition ppos);
240+
241+
/** Gets an expression being returned by this method. */
242+
Expr getAReturnExpr();
243+
}
244+
245+
class BooleanMethodCall extends Expr {
246+
BooleanMethod getMethod();
247+
248+
Expr getArgument(ArgumentPosition apos);
249+
}
210250
}
211251

212252
/** Provides guards-related predicates and classes. */
@@ -503,6 +543,8 @@ module Make<LocationSig Location, InputSig<Location> Input> {
503543
predicate hasInputFromBlock(SsaDefinition inp, BasicBlock bb);
504544
}
505545

546+
predicate parameterDefinition(Parameter p, SsaDefinition def);
547+
506548
/**
507549
* Holds if `guard` evaluating to `val` ensures that:
508550
* `e <= k` when `upper = true`
@@ -525,8 +567,6 @@ module Make<LocationSig Location, InputSig<Location> Input> {
525567
* Holds if the assumption that `g1` has been evaluated to `v1` implies that
526568
* `g2` has been evaluated to `v2`, that is, the evaluation of `g2` to `v2`
527569
* dominates the evaluation of `g1` to `v1`.
528-
*
529-
* This predicate can be instantiated with `CustomGuard<..>::additionalImpliesStep`.
530570
*/
531571
default predicate additionalImpliesStep(PreGuard g1, GuardValue v1, PreGuard g2, GuardValue v2) {
532572
none()
@@ -859,6 +899,11 @@ module Make<LocationSig Location, InputSig<Location> Input> {
859899
impliesStepSsaGuard(def0, v0, guard, v)
860900
)
861901
or
902+
exists(Guard g0, GuardValue v0 |
903+
guardControls(g0, v0, tgtGuard, tgtVal) and
904+
CustomGuard::additionalImpliesStep(g0, v0, guard, v)
905+
)
906+
or
862907
exists(Guard g0, GuardValue v0 |
863908
guardControls(g0, v0, tgtGuard, tgtVal) and
864909
additionalImpliesStep(g0, v0, guard, v)
@@ -902,6 +947,7 @@ module Make<LocationSig Location, InputSig<Location> Input> {
902947
*/
903948
predicate nullGuard(Guard guard, GuardValue v, Expr e, boolean isNull) {
904949
impliesStep2(guard, v, e, any(GuardValue gv | gv.isNullness(isNull))) or
950+
CustomGuard::additionalImpliesStep(guard, v, e, any(GuardValue gv | gv.isNullness(isNull))) or
905951
additionalImpliesStep(guard, v, e, any(GuardValue gv | gv.isNullness(isNull)))
906952
}
907953

@@ -944,47 +990,12 @@ module Make<LocationSig Location, InputSig<Location> Input> {
944990
)
945991
}
946992

947-
signature module CustomGuardInputSig {
948-
class ParameterPosition {
949-
/** Gets a textual representation of this element. */
950-
bindingset[this]
951-
string toString();
952-
}
953-
954-
class ArgumentPosition {
955-
/** Gets a textual representation of this element. */
956-
bindingset[this]
957-
string toString();
958-
}
959-
960-
/**
961-
* Holds if the parameter position `ppos` matches the argument position
962-
* `apos`.
963-
*/
964-
predicate parameterMatch(ParameterPosition ppos, ArgumentPosition apos);
965-
966-
/** A non-overridable method with a boolean return value. */
967-
class BooleanMethod {
968-
SsaDefinition getParameter(ParameterPosition ppos);
969-
970-
Expr getAReturnExpr();
971-
}
972-
973-
class BooleanMethodCall extends Expr {
974-
BooleanMethod getMethod();
975-
976-
Expr getArgument(ArgumentPosition apos);
977-
}
978-
}
979-
980993
/**
981994
* Provides an implementation of guard implication logic for custom
982995
* wrappers. This can be used to instantiate the `additionalImpliesStep`
983996
* predicate.
984997
*/
985-
module CustomGuard<CustomGuardInputSig CustomGuardInput> {
986-
private import CustomGuardInput
987-
998+
private module CustomGuard {
988999
final private class FinalExpr = Expr;
9891000

9901001
private class ReturnExpr extends FinalExpr {
@@ -1010,7 +1021,7 @@ module Make<LocationSig Location, InputSig<Location> Input> {
10101021
) {
10111022
exists(BooleanMethod m, SsaDefinition param |
10121023
m.getAReturnExpr() = ret and
1013-
m.getParameter(ppos) = param
1024+
parameterDefinition(m.getParameter(ppos), param)
10141025
|
10151026
exists(Guard g0, GuardValue v0 |
10161027
g0.directlyValueControls(ret.getBasicBlock(), v0) and

0 commit comments

Comments
 (0)