Files
codeql/java/ql/src/Likely Bugs/Concurrency/EmptyRunMethodInThread.ql
Anders Schack-Mulligen ae44b90456 Java: Normalize parentheses.
2018-11-28 15:01:25 +01:00

63 lines
2.2 KiB
Plaintext

/**
* @name Useless run() method in thread
* @description Thread instances that neither get an argument of type 'Runnable' passed to their
* constructor nor override the 'Thread.run' method are likely to have no effect.
* @kind problem
* @problem.severity warning
* @precision low
* @id java/empty-run-method-in-thread
* @tags reliability
* correctness
* concurrency
*/
import java
class ThreadClass extends Class {
ThreadClass() { this.hasQualifiedName("java.lang", "Thread") }
/**
* Any constructor of `java.lang.Thread` _without_ a parameter of type `Runnable`;
* these require overriding the `Thread.run()` method in order to do anything useful.
*/
Constructor getAConstructorWithoutRunnableParam() {
result = this.getAConstructor() and
(
result.getNumberOfParameters() = 0
or
result.getNumberOfParameters() = 1 and
result.getParameter(0).getType().(RefType).hasQualifiedName("java.lang", "String")
or
result.getNumberOfParameters() = 2 and
result.getParameter(0).getType().(RefType).hasQualifiedName("java.lang", "ThreadGroup") and
result.getParameter(1).getType().(RefType).hasQualifiedName("java.lang", "String")
)
}
/**
* Any constructor of `java.lang.Thread` _with_ a parameter of type `Runnable`;
* these ensure that the `Thread.run()` method calls the `Runnable.run()` method.
*/
Constructor getAConstructorWithRunnableParam() {
result = this.getAConstructor() and
not exists(Constructor c | c = result | result = this.getAConstructorWithoutRunnableParam())
}
}
from ClassInstanceExpr cie, ThreadClass thread, Class emptythread
where
emptythread.hasSupertype*(thread) and
not exists(Class middle, Method run |
run.hasName("run") and
run.isPublic() and
not run.isAbstract() and
run.hasNoParameters() and
middle.getAMethod() = run and
middle.hasSupertype+(thread) and
emptythread.hasSupertype*(middle)
) and
not cie.getConstructor().callsConstructor*(thread.getAConstructorWithRunnableParam()) and
cie.getType().(RefType).getSourceDeclaration() = emptythread
select cie,
"Thread " + emptythread.getName() + " has a useless empty run() inherited from java.lang.Thread."