Skip to content

Commit 50a5300

Browse files
committed
QL: Refine 'redundant override' query
1 parent 4f93f2b commit 50a5300

File tree

3 files changed

+217
-40
lines changed

3 files changed

+217
-40
lines changed

ql/ql/src/queries/style/RedundantOverride.ql

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,14 @@
1010

1111
import ql
1212

13-
private predicate redundantOverride(ClassPredicate pred, ClassPredicate sup) {
13+
/** Holds if `pred` overrides super predicate `sup` by forwarding via `mc`. */
14+
private predicate forwardingOverride(ClassPredicate pred, MemberCall mc, ClassPredicate sup) {
1415
pred.overrides(sup) and
15-
// Can be made more precise, but rules out overrides needed for disambiguation
16-
count(pred.getDeclaringType().getASuperType()) <= 1 and
17-
exists(MemberCall mc |
18-
mc.getBase() instanceof Super and
19-
mc.getTarget() = sup and
20-
not exists(pred.getQLDoc())
21-
|
16+
mc.getBase() instanceof Super and
17+
mc.getTarget() = sup and
18+
not exists(pred.getQLDoc()) and
19+
forall(int i, VarDecl p | p = pred.getParameter(i) | mc.getArgument(i) = p.getAnAccess()) and
20+
(
2221
pred.getBody() =
2322
any(ComparisonFormula comp |
2423
comp.getOperator() = "=" and
@@ -31,6 +30,31 @@ private predicate redundantOverride(ClassPredicate pred, ClassPredicate sup) {
3130
)
3231
}
3332

33+
private predicate forwardingOverrideProj(ClassPredicate pred, ClassPredicate sup) {
34+
forwardingOverride(pred, _, sup)
35+
}
36+
37+
private ClassPredicate getUltimateDef(ClassPredicate p) {
38+
forwardingOverrideProj*(p, result) and
39+
not forwardingOverrideProj(result, _)
40+
}
41+
42+
private predicate redundantOverride(ClassPredicate pred, ClassPredicate sup) {
43+
exists(MemberCall mc |
44+
forwardingOverride(pred, mc, sup) and
45+
// overridden to provide more precise QL doc
46+
not exists(pred.getQLDoc()) and
47+
// overridden to disambiguate
48+
not exists(ClassPredicate other |
49+
getUltimateDef(sup) != getUltimateDef(other) and
50+
pred.getDeclaringType().getASuperType+() = other.getDeclaringType() and
51+
not sup.overrides*(other) and
52+
other.getName() = pred.getName() and
53+
other.getArity() = pred.getArity()
54+
)
55+
)
56+
}
57+
3458
from ClassPredicate pred, ClassPredicate sup
3559
where redundantOverride(pred, sup)
3660
select pred, "Redundant override of $@ predicate", sup, "this"
Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,11 @@
1-
| RedundantOverride.qll:12:16:12:19 | ClassPredicate pred | Redundant override of $@ predicate | RedundantOverride.qll:4:7:4:10 | ClassPredicate pred | this |
2-
| RedundantOverride.qll:16:16:16:19 | ClassPredicate pred | Redundant override of $@ predicate | RedundantOverride.qll:4:7:4:10 | ClassPredicate pred | this |
3-
| RedundantOverride.qll:47:22:47:26 | ClassPredicate pred3 | Redundant override of $@ predicate | RedundantOverride.qll:8:13:8:17 | ClassPredicate pred3 | this |
4-
| RedundantOverride.qll:51:16:51:19 | ClassPredicate pred | Redundant override of $@ predicate | RedundantOverride.qll:4:7:4:10 | ClassPredicate pred | this |
1+
| RedundantOverride.qll:9:18:9:21 | ClassPredicate pred | Redundant override of $@ predicate | RedundantOverride.qll:5:9:5:12 | ClassPredicate pred | this |
2+
| RedundantOverride.qll:21:18:21:21 | ClassPredicate pred | Redundant override of $@ predicate | RedundantOverride.qll:17:9:17:12 | ClassPredicate pred | this |
3+
| RedundantOverride.qll:110:24:110:27 | ClassPredicate pred | Redundant override of $@ predicate | RedundantOverride.qll:106:15:106:18 | ClassPredicate pred | this |
4+
| RedundantOverride.qll:124:18:124:21 | ClassPredicate pred | Redundant override of $@ predicate | RedundantOverride.qll:118:9:118:12 | ClassPredicate pred | this |
5+
| RedundantOverride.qll:128:18:128:21 | ClassPredicate pred | Redundant override of $@ predicate | RedundantOverride.qll:118:9:118:12 | ClassPredicate pred | this |
6+
| RedundantOverride.qll:132:18:132:21 | ClassPredicate pred | Redundant override of $@ predicate | RedundantOverride.qll:128:18:128:21 | ClassPredicate pred | this |
7+
| RedundantOverride.qll:150:18:150:21 | ClassPredicate pred | Redundant override of $@ predicate | RedundantOverride.qll:140:9:140:12 | ClassPredicate pred | this |
8+
| RedundantOverride.qll:164:18:164:21 | ClassPredicate pred | Redundant override of $@ predicate | RedundantOverride.qll:158:9:158:12 | ClassPredicate pred | this |
9+
| RedundantOverride.qll:168:18:168:21 | ClassPredicate pred | Redundant override of $@ predicate | RedundantOverride.qll:158:9:158:12 | ClassPredicate pred | this |
10+
| RedundantOverride.qll:172:18:172:21 | ClassPredicate pred | Redundant override of $@ predicate | RedundantOverride.qll:168:18:168:21 | ClassPredicate pred | this |
11+
| RedundantOverride.qll:176:18:176:21 | ClassPredicate pred | Redundant override of $@ predicate | RedundantOverride.qll:168:18:168:21 | ClassPredicate pred | this |
Lines changed: 174 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,198 @@
1-
class Foo extends string {
2-
Foo() { this = "Foo" }
1+
module Test1 {
2+
class Foo extends int {
3+
Foo() { this = 1 }
34

4-
Foo pred() { none() }
5+
Foo pred() { result = this }
6+
}
57

6-
Foo pred2() { none() }
7-
8-
predicate pred3() { none() }
8+
class Bar extends Foo {
9+
override Foo pred() { result = Foo.super.pred() } // BAD
10+
}
911
}
1012

11-
class Bar1 extends Foo {
12-
override Foo pred() { result = Foo.super.pred() } // BAD
13+
module Test2 {
14+
class Foo extends int {
15+
Foo() { this = 1 }
16+
17+
Foo pred() { result = this }
18+
}
19+
20+
class Bar extends Foo {
21+
override Foo pred() { result = super.pred() } // BAD
22+
}
1323
}
1424

15-
class Bar2 extends Foo {
16-
override Foo pred() { result = super.pred() } // BAD
25+
module Test3 {
26+
class Foo extends int {
27+
Foo() { this = [1 .. 3] }
28+
29+
Foo pred() { any() }
30+
}
31+
32+
class Bar extends Foo {
33+
Bar() { this = 2 }
34+
}
35+
36+
class Baz extends Foo {
37+
Baz() { this = 3 }
38+
39+
override Bar pred() { result = super.pred() } // GOOD (refined return type)
40+
}
1741
}
1842

19-
class Bar3 extends Foo {
20-
override Bar3 pred() { result = super.pred() } // GOOD (refined return type)
43+
module Test4 {
44+
class Foo extends int {
45+
Foo() { this = [1, 2] }
46+
47+
Foo pred() { result = 2 }
48+
}
49+
50+
class Bar extends Foo {
51+
Bar() { this = 1 }
52+
53+
override Foo pred() { result = this } // GOOD
54+
}
2155
}
2256

23-
class Bar4 extends Foo {
24-
override Foo pred() { any() } // GOOD
57+
module Test5 {
58+
class Foo extends int {
59+
Foo() { this = 1 }
60+
61+
Foo pred() { result = this }
62+
}
63+
64+
class Bar extends Foo {
65+
/** My own overriding QL doc. */
66+
override Foo pred() { result = super.pred() } // GOOD
67+
}
2568
}
2669

27-
class Bar5 extends Foo {
28-
/** My own overriding QL doc. */
29-
override Foo pred() { result = super.pred() } // GOOD
70+
module Test6 {
71+
class Foo extends int {
72+
Foo() { this = [1, 2] }
73+
74+
Foo pred() { result = 1 }
75+
76+
Foo pred2() { result = 2 }
77+
}
78+
79+
class Bar extends Foo {
80+
override Foo pred() { result = super.pred2() } // GOOD
81+
}
3082
}
3183

32-
class Bar6 extends Foo {
33-
override Foo pred() { result = super.pred2() } // GOOD
84+
module Test7 {
85+
class Foo extends int {
86+
Foo() { this = [1, 2] }
87+
88+
Foo pred() { result = 2 }
89+
}
90+
91+
class Bar extends int {
92+
Bar() { this = 1 }
93+
94+
Foo pred() { result = this }
95+
}
96+
97+
class Baz extends Foo, Bar {
98+
override Foo pred() { result = Foo.super.pred() } // GOOD (disambiguate)
99+
}
34100
}
35101

36-
class Bar7 extends string {
37-
Bar7() { this = "Bar7" }
102+
module Test8 {
103+
class Foo extends int {
104+
Foo() { this = 1 }
38105

39-
Foo pred() { any() }
106+
predicate pred(Foo f) { f = this }
107+
}
108+
109+
class Bar extends Foo {
110+
override predicate pred(Foo f) { super.pred(f) } // BAD
111+
}
40112
}
41113

42-
class Bar8 extends Foo, Bar7 {
43-
override Foo pred() { result = Foo.super.pred() } // GOOD
114+
module Test9 {
115+
class Foo extends int {
116+
Foo() { this = [1, 2] }
117+
118+
Foo pred() { result = this }
119+
}
120+
121+
class Bar extends Foo {
122+
Bar() { this = 1 }
123+
124+
override Foo pred() { Foo.super.pred() = result } // BAD
125+
}
126+
127+
class Baz1 extends Foo, Bar {
128+
override Foo pred() { Foo.super.pred() = result } // BAD
129+
}
130+
131+
class Baz2 extends Foo, Baz1 {
132+
override Foo pred() { Baz1.super.pred() = result } // BAD
133+
}
44134
}
45135

46-
class Bar9 extends Foo {
47-
override predicate pred3() { super.pred3() } // BAD
136+
module Test10 {
137+
class Foo extends int {
138+
Foo() { this = [1, 2] }
139+
140+
Foo pred() { result = 1 }
141+
}
142+
143+
class Bar extends int {
144+
Bar() { this = 1 }
145+
146+
Foo pred(int i) { none() }
147+
}
148+
149+
class Baz1 extends Foo, Bar {
150+
override Foo pred() { result = Foo.super.pred() } // BAD
151+
}
48152
}
49153

50-
class Bar10 extends Foo {
51-
override Foo pred() { Foo.super.pred() = result } // BAD
154+
module Test11 {
155+
class Foo extends int {
156+
Foo() { this = [1 .. 4] }
157+
158+
Foo pred() { result = 1 }
159+
}
160+
161+
class Bar1 extends Foo {
162+
Bar1() { this = [1 .. 3] }
163+
164+
override Foo pred() { Foo.super.pred() = result } // BAD
165+
}
166+
167+
class Bar2 extends Foo, Bar1 {
168+
override Foo pred() { Foo.super.pred() = result } // BAD
169+
}
170+
171+
class Bar3 extends Foo, Bar2 {
172+
override Foo pred() { Bar2.super.pred() = result } // BAD
173+
}
174+
175+
class Bar4 extends Bar2, Bar3 {
176+
override Foo pred() { result = Bar2.super.pred() } // BAD
177+
}
178+
179+
class Bar5 extends Foo {
180+
Bar5() { this = [1 .. 2] }
181+
182+
override Foo pred() { result = this } // GOOD
183+
}
184+
185+
class Bar6 extends Bar4, Bar5 {
186+
override Foo pred() { result = Bar4.super.pred() } // GOOD (dismambiguate)
187+
}
188+
189+
class Bar7 extends Bar6 {
190+
Bar7() { this = 1 }
191+
192+
override Foo pred() { result = 2 } // GOOD
193+
}
194+
195+
class Bar8 extends Bar6, Bar7 {
196+
override Foo pred() { result = Bar6.super.pred() } // GOOD (specialize)
197+
}
52198
}

0 commit comments

Comments
 (0)