Merge pull request #9827 from erik-krogh/overrideAny

QL: Query for detecting unused parameter in override methods
This commit is contained in:
Erik Krogh Kristensen 2022-11-11 15:17:48 +01:00 коммит произвёл GitHub
Родитель ddbcdcb4ba c1727ba005
Коммит 2291f18695
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
3 изменённых файлов: 69 добавлений и 26 удалений

Просмотреть файл

@ -0,0 +1,27 @@
import ql
/**
* Holds if we assume `t` is a small type, and
* variables of this type are therefore not an issue in cartesian products.
*/
predicate isSmallType(Type t) {
t.getName() = "string" // DataFlow::Configuration and the like
or
exists(NewType newType | newType = t.getDeclaration() |
forex(NewTypeBranch branch | branch = newType.getABranch() | branch.getArity() = 0)
)
or
t.getName() = "boolean"
or
exists(NewType newType | newType = t.getDeclaration() |
forex(NewTypeBranch branch | branch = newType.getABranch() |
isSmallType(branch.getReturnType())
)
)
or
exists(NewTypeBranch branch | t = branch.getReturnType() |
forall(Type param | param = branch.getParameterType(_) | isSmallType(param))
)
or
isSmallType(t.getASuperType())
}

Просмотреть файл

@ -10,6 +10,7 @@
*/
import ql
import codeql_ql.performance.VarUnusedInDisjunctQuery
/**
* Holds if `node` bind `var` in a (transitive) child node.
@ -48,32 +49,6 @@ predicate alwaysBindsVar(VarDef var, AstNode node) {
exists(IfFormula ifForm | ifForm = node | alwaysBindsVar(var, ifForm.getCondition()))
}
/**
* Holds if we assume `t` is a small type, and
* variables of this type are therefore not an issue in cartesian products.
*/
predicate isSmallType(Type t) {
t.getName() = "string" // DataFlow::Configuration and the like
or
exists(NewType newType | newType = t.getDeclaration() |
forex(NewTypeBranch branch | branch = newType.getABranch() | branch.getArity() = 0)
)
or
t.getName() = "boolean"
or
exists(NewType newType | newType = t.getDeclaration() |
forex(NewTypeBranch branch | branch = newType.getABranch() |
isSmallType(branch.getReturnType())
)
)
or
exists(NewTypeBranch branch | t = branch.getReturnType() |
forall(Type param | param = branch.getParameterType(_) | isSmallType(param))
)
or
isSmallType(t.getASuperType())
}
/**
* Holds if `pred` is inlined.
*/

Просмотреть файл

@ -0,0 +1,41 @@
/**
* @name Override with unmentioned parameter
* @description A predicate that overrides the default behavior but doesn't mention a parameter is suspicious.
* @kind problem
* @problem.severity warning
* @id ql/override-any
* @precision high
*/
import ql
import codeql_ql.performance.VarUnusedInDisjunctQuery
AstNode param(Predicate pred, string name, Type t) {
result = pred.getParameter(_) and
result.(VarDecl).getName() = name and
result.(VarDecl).getType() = t
or
result = pred.getReturnTypeExpr() and
name = "result" and
t = pred.getReturnType()
}
predicate hasAccess(Predicate pred, string name) {
exists(param(pred, name, _).(VarDecl).getAnAccess())
or
name = "result" and
exists(param(pred, name, _)) and
exists(ResultAccess res | res.getEnclosingPredicate() = pred)
}
from Predicate pred, AstNode param, string name, Type paramType
where
pred.hasAnnotation("override") and
param = param(pred, name, paramType) and
not hasAccess(pred, name) and
not pred.getBody() instanceof NoneCall and
exists(pred.getBody()) and
not isSmallType(pred.getParent().(Class).getType()) and
not isSmallType(paramType)
select pred, "Override predicate doesn't mention $@. Maybe mention it in a 'exists(" + name + ")'?",
param, name