Skip to content

Commit 2291f18

Browse files
authored
Merge pull request github#9827 from erik-krogh/overrideAny
QL: Query for detecting unused parameter in override methods
2 parents ddbcdcb + c1727ba commit 2291f18

File tree

3 files changed

+69
-26
lines changed

3 files changed

+69
-26
lines changed
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import ql
2+
3+
/**
4+
* Holds if we assume `t` is a small type, and
5+
* variables of this type are therefore not an issue in cartesian products.
6+
*/
7+
predicate isSmallType(Type t) {
8+
t.getName() = "string" // DataFlow::Configuration and the like
9+
or
10+
exists(NewType newType | newType = t.getDeclaration() |
11+
forex(NewTypeBranch branch | branch = newType.getABranch() | branch.getArity() = 0)
12+
)
13+
or
14+
t.getName() = "boolean"
15+
or
16+
exists(NewType newType | newType = t.getDeclaration() |
17+
forex(NewTypeBranch branch | branch = newType.getABranch() |
18+
isSmallType(branch.getReturnType())
19+
)
20+
)
21+
or
22+
exists(NewTypeBranch branch | t = branch.getReturnType() |
23+
forall(Type param | param = branch.getParameterType(_) | isSmallType(param))
24+
)
25+
or
26+
isSmallType(t.getASuperType())
27+
}

ql/ql/src/queries/performance/VarUnusedInDisjunct.ql

Lines changed: 1 addition & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
*/
1111

1212
import ql
13+
import codeql_ql.performance.VarUnusedInDisjunctQuery
1314

1415
/**
1516
* Holds if `node` bind `var` in a (transitive) child node.
@@ -48,32 +49,6 @@ predicate alwaysBindsVar(VarDef var, AstNode node) {
4849
exists(IfFormula ifForm | ifForm = node | alwaysBindsVar(var, ifForm.getCondition()))
4950
}
5051

51-
/**
52-
* Holds if we assume `t` is a small type, and
53-
* variables of this type are therefore not an issue in cartesian products.
54-
*/
55-
predicate isSmallType(Type t) {
56-
t.getName() = "string" // DataFlow::Configuration and the like
57-
or
58-
exists(NewType newType | newType = t.getDeclaration() |
59-
forex(NewTypeBranch branch | branch = newType.getABranch() | branch.getArity() = 0)
60-
)
61-
or
62-
t.getName() = "boolean"
63-
or
64-
exists(NewType newType | newType = t.getDeclaration() |
65-
forex(NewTypeBranch branch | branch = newType.getABranch() |
66-
isSmallType(branch.getReturnType())
67-
)
68-
)
69-
or
70-
exists(NewTypeBranch branch | t = branch.getReturnType() |
71-
forall(Type param | param = branch.getParameterType(_) | isSmallType(param))
72-
)
73-
or
74-
isSmallType(t.getASuperType())
75-
}
76-
7752
/**
7853
* Holds if `pred` is inlined.
7954
*/
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/**
2+
* @name Override with unmentioned parameter
3+
* @description A predicate that overrides the default behavior but doesn't mention a parameter is suspicious.
4+
* @kind problem
5+
* @problem.severity warning
6+
* @id ql/override-any
7+
* @precision high
8+
*/
9+
10+
import ql
11+
import codeql_ql.performance.VarUnusedInDisjunctQuery
12+
13+
AstNode param(Predicate pred, string name, Type t) {
14+
result = pred.getParameter(_) and
15+
result.(VarDecl).getName() = name and
16+
result.(VarDecl).getType() = t
17+
or
18+
result = pred.getReturnTypeExpr() and
19+
name = "result" and
20+
t = pred.getReturnType()
21+
}
22+
23+
predicate hasAccess(Predicate pred, string name) {
24+
exists(param(pred, name, _).(VarDecl).getAnAccess())
25+
or
26+
name = "result" and
27+
exists(param(pred, name, _)) and
28+
exists(ResultAccess res | res.getEnclosingPredicate() = pred)
29+
}
30+
31+
from Predicate pred, AstNode param, string name, Type paramType
32+
where
33+
pred.hasAnnotation("override") and
34+
param = param(pred, name, paramType) and
35+
not hasAccess(pred, name) and
36+
not pred.getBody() instanceof NoneCall and
37+
exists(pred.getBody()) and
38+
not isSmallType(pred.getParent().(Class).getType()) and
39+
not isSmallType(paramType)
40+
select pred, "Override predicate doesn't mention $@. Maybe mention it in a 'exists(" + name + ")'?",
41+
param, name

0 commit comments

Comments
 (0)