Files
codeql/python/ql/src/Variables/UnusedModuleVariable.ql
Taus Brock-Nannestad f07a7bf8cf Python: Autoformat everything using qlformat.
Will need subsequent PRs fixing up test failures (due to deprecated
methods moving around), but other than that everything should be
straight-forward.
2020-07-07 15:43:52 +02:00

67 lines
2.1 KiB
Plaintext

/**
* @name Unused global variable
* @description Global variable is defined but not used
* @kind problem
* @tags efficiency
* useless-code
* external/cwe/cwe-563
* @problem.severity recommendation
* @sub-severity low
* @precision high
* @id py/unused-global-variable
*/
import python
import Definition
/**
* Whether the module contains an __all__ definition,
* but it is more complex than a simple list of strings
*/
predicate complex_all(Module m) {
exists(Assign a, GlobalVariable all |
a.defines(all) and a.getScope() = m and all.getId() = "__all__"
|
not a.getValue() instanceof List
or
exists(Expr e | e = a.getValue().(List).getAnElt() | not e instanceof StrConst)
)
or
exists(Call c, GlobalVariable all |
c.getFunc().(Attribute).getObject() = all.getALoad() and
c.getScope() = m and
all.getId() = "__all__"
)
}
predicate unused_global(Name unused, GlobalVariable v) {
not exists(ImportingStmt is | is.contains(unused)) and
forex(DefinitionNode defn | defn.getNode() = unused |
not defn.getValue().getNode() instanceof FunctionExpr and
not defn.getValue().getNode() instanceof ClassExpr and
not exists(Name u |
// A use of the variable
u.uses(v)
|
// That is reachable from this definition, directly
defn.strictlyReaches(u.getAFlowNode())
or
// indirectly
defn.getBasicBlock().reachesExit() and u.getScope() != unused.getScope()
) and
not unused.getEnclosingModule().getAnExport() = v.getId() and
not exists(unused.getParentNode().(ClassDef).getDefinedClass().getADecorator()) and
not exists(unused.getParentNode().(FunctionDef).getDefinedFunction().getADecorator()) and
unused.defines(v) and
not name_acceptable_for_unused_variable(v) and
not complex_all(unused.getEnclosingModule())
)
}
from Name unused, GlobalVariable v
where
unused_global(unused, v) and
// If unused is part of a tuple, count it as unused if all elements of that tuple are unused.
forall(Name el | el = unused.getParentNode().(Tuple).getAnElt() | unused_global(el, _))
select unused, "The global variable '" + v.getId() + "' is not used."