mirror of
https://github.com/github/codeql.git
synced 2025-12-17 01:03:14 +01:00
QL: Improve dead-code query
This commit is contained in:
@@ -567,7 +567,7 @@ class ClasslessPredicate extends TClasslessPredicate, Predicate, ModuleDeclarati
|
|||||||
override predicate isPrivate() { Predicate.super.isPrivate() }
|
override predicate isPrivate() { Predicate.super.isPrivate() }
|
||||||
|
|
||||||
/** Holds if this classless predicate is a signature predicate with no body. */
|
/** Holds if this classless predicate is a signature predicate with no body. */
|
||||||
predicate isSignature() { not exists(this.getBody()) }
|
override predicate isSignature() { not exists(this.getBody()) }
|
||||||
|
|
||||||
override QLDoc getQLDoc() {
|
override QLDoc getQLDoc() {
|
||||||
result = any(TopLevel m).getQLDocFor(this)
|
result = any(TopLevel m).getQLDocFor(this)
|
||||||
@@ -836,6 +836,12 @@ class Module extends TModule, ModuleDeclaration {
|
|||||||
toMock(result) = mod.asRight().getMember(i)
|
toMock(result) = mod.asRight().getMember(i)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pragma[nomagic]
|
||||||
|
Declaration getDeclaration(string name) {
|
||||||
|
result = this.getAMember() and
|
||||||
|
name = result.getName()
|
||||||
|
}
|
||||||
|
|
||||||
QLDoc getQLDocFor(AstNode m) {
|
QLDoc getQLDocFor(AstNode m) {
|
||||||
exists(int i | result = this.getMember(i) and m = this.getMember(i + 1))
|
exists(int i | result = this.getMember(i) and m = this.getMember(i + 1))
|
||||||
}
|
}
|
||||||
@@ -885,6 +891,33 @@ class ModuleMember extends TModuleMember, AstNode {
|
|||||||
predicate isFinal() { this.hasAnnotation("final") }
|
predicate isFinal() { this.hasAnnotation("final") }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private newtype TDeclarationKind =
|
||||||
|
TClassKind() or
|
||||||
|
TModuleKind() or
|
||||||
|
TPredicateKind(int arity) { arity = any(Predicate p).getArity() }
|
||||||
|
|
||||||
|
private TDeclarationKind getDeclarationKind(Declaration d) {
|
||||||
|
d instanceof Class and result = TClassKind()
|
||||||
|
or
|
||||||
|
d instanceof Module and result = TModuleKind()
|
||||||
|
or
|
||||||
|
d = any(Predicate p | result = TPredicateKind(p.getArity()))
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Holds if module `m` must implement signature declaration `d` with name `name` and kind `kind`. */
|
||||||
|
pragma[nomagic]
|
||||||
|
private predicate mustImplement(Module m, string name, TDeclarationKind kind, Declaration d) {
|
||||||
|
d = m.getImplements(_).getResolvedType().getDeclaration().(Module).getAMember() and
|
||||||
|
name = d.getName() and
|
||||||
|
kind = getDeclarationKind(d)
|
||||||
|
}
|
||||||
|
|
||||||
|
pragma[nomagic]
|
||||||
|
private Declaration getDeclaration(Module m, string name, TDeclarationKind kind) {
|
||||||
|
result = m.getDeclaration(name) and
|
||||||
|
kind = getDeclarationKind(result)
|
||||||
|
}
|
||||||
|
|
||||||
/** A declaration. E.g. a class, type, predicate, newtype... */
|
/** A declaration. E.g. a class, type, predicate, newtype... */
|
||||||
class Declaration extends TDeclaration, AstNode {
|
class Declaration extends TDeclaration, AstNode {
|
||||||
/** Gets the name of this declaration. */
|
/** Gets the name of this declaration. */
|
||||||
@@ -899,6 +932,16 @@ class Declaration extends TDeclaration, AstNode {
|
|||||||
or
|
or
|
||||||
result = any(Class c).getQLDocFor(this)
|
result = any(Class c).getQLDocFor(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
predicate isSignature() { this.hasAnnotation("signature") }
|
||||||
|
|
||||||
|
/** Holds if this declaration implements `other`. */
|
||||||
|
predicate implements(Declaration other) {
|
||||||
|
exists(Module m, string name, TDeclarationKind kind |
|
||||||
|
this = getDeclaration(m, name, kind) and
|
||||||
|
mustImplement(m, name, kind, other)
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** An entity that can be declared in a module. */
|
/** An entity that can be declared in a module. */
|
||||||
|
|||||||
@@ -186,6 +186,16 @@ private AstNode aliveStep(AstNode prev) {
|
|||||||
result = prev.(Module).getImplements(_)
|
result = prev.(Module).getImplements(_)
|
||||||
or
|
or
|
||||||
result = prev.(PredicateExpr).getQualifier()
|
result = prev.(PredicateExpr).getQualifier()
|
||||||
|
or
|
||||||
|
// a module argument is live if the constructed module is
|
||||||
|
result = prev.(ModuleExpr).getArgument(_)
|
||||||
|
or
|
||||||
|
// a type declaration is live if a reference to it is live
|
||||||
|
result = prev.(TypeExpr).getResolvedType().getDeclaration()
|
||||||
|
or
|
||||||
|
// a module member that implements a signature member is live if the module is
|
||||||
|
prev.(Module).getAMember() = result and
|
||||||
|
result.(Declaration).implements(_)
|
||||||
}
|
}
|
||||||
|
|
||||||
private AstNode deprecated() {
|
private AstNode deprecated() {
|
||||||
|
|||||||
@@ -1,8 +1,5 @@
|
|||||||
| Foo.qll:4:21:4:25 | ClasslessPredicate dead1 | This code is never used, and it's not publicly exported. |
|
| Foo.qll:4:21:4:25 | ClasslessPredicate dead1 | This code is never used, and it's not publicly exported. |
|
||||||
| Foo.qll:8:13:8:17 | ClasslessPredicate dead2 | This code is never used, and it's not publicly exported. |
|
| Foo.qll:8:13:8:17 | ClasslessPredicate dead2 | This code is never used, and it's not publicly exported. |
|
||||||
| Foo.qll:42:16:42:21 | Module Input1 | This code is never used, and it's not publicly exported. |
|
|
||||||
| Foo.qll:46:16:46:21 | Module Input2 | This code is never used, and it's not publicly exported. |
|
| Foo.qll:46:16:46:21 | Module Input2 | This code is never used, and it's not publicly exported. |
|
||||||
| Foo.qll:50:16:50:21 | Module Input3 | This code is never used, and it's not publicly exported. |
|
|
||||||
| Foo.qll:56:16:56:17 | Module M2 | This code is never used, and it's not publicly exported. |
|
| Foo.qll:56:16:56:17 | Module M2 | This code is never used, and it's not publicly exported. |
|
||||||
| Foo.qll:64:15:64:20 | Class CImpl1 | This code is never used, and it's not publicly exported. |
|
|
||||||
| Foo.qll:68:15:68:20 | Class CImpl2 | This code is never used, and it's not publicly exported. |
|
| Foo.qll:68:15:68:20 | Class CImpl2 | This code is never used, and it's not publicly exported. |
|
||||||
|
|||||||
Reference in New Issue
Block a user