Skip to content

Commit 767d55b

Browse files
authored
Merge pull request #20013 from kaspersv/kaspersv/ql4ql-discard-entity-preds-alive
QL4QL: Discard predicates are always alive
2 parents 18760b4 + c7a3b65 commit 767d55b

File tree

3 files changed

+26
-2
lines changed

3 files changed

+26
-2
lines changed

ql/ql/src/codeql_ql/ast/Ast.qll

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2554,6 +2554,10 @@ private class LocalQArg extends AnnotationArg {
25542554
LocalQArg() { this.getValue() = "local?" }
25552555
}
25562556

2557+
private class DiscardEntityArg extends AnnotationArg {
2558+
DiscardEntityArg() { this.getValue() = "discard_entity" }
2559+
}
2560+
25572561
private class MonotonicAggregatesArg extends AnnotationArg {
25582562
MonotonicAggregatesArg() { this.getValue() = "monotonicAggregates" }
25592563
}
@@ -2641,6 +2645,15 @@ class OverlayLocalQ extends Annotation {
26412645
override string toString() { result = "overlay[local?]" }
26422646
}
26432647

2648+
/** An `overlay[discard_entity]` annotation. */
2649+
class OverlayDiscardEntity extends Annotation {
2650+
OverlayDiscardEntity() {
2651+
this.getName() = "overlay" and this.getArgs(0) instanceof DiscardEntityArg
2652+
}
2653+
2654+
override string toString() { result = "overlay[discard_entity]" }
2655+
}
2656+
26442657
/** A `language[monotonicAggregates]` annotation. */
26452658
class MonotonicAggregates extends Annotation {
26462659
MonotonicAggregates() { this.getArgs(0) instanceof MonotonicAggregatesArg }

ql/ql/src/codeql_ql/style/DeadCodeQuery.qll

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@ private AstNode queryPredicate() {
3939
result = queryPredicate().getAChild()
4040
}
4141

42+
private AstNode discardPredicate() {
43+
result.(Predicate).getAnAnnotation() instanceof OverlayDiscardEntity
44+
}
45+
4246
AstNode hackyShouldBeTreatedAsAlive() {
4347
// Stages from the shared DataFlow impl are copy-pasted, so predicates that are dead in one stage are not dead in another.
4448
result = any(Module mod | mod.getName().matches("Stage%")).getAMember().(ClasslessPredicate) and
@@ -58,7 +62,7 @@ AstNode hackyShouldBeTreatedAsAlive() {
5862
*/
5963
private AstNode alive() {
6064
//
61-
// The 4 base cases.
65+
// The 6 base cases.
6266
//
6367
// 1) everything that can be imported.
6468
result = publicApi()
@@ -73,7 +77,11 @@ private AstNode alive() {
7377
// 4) Things that aren't really alive, but that this query treats as live.
7478
result = hackyShouldBeTreatedAsAlive()
7579
or
76-
result instanceof TopLevel // toplevel is always alive.
80+
// 5) discard predicates
81+
result = discardPredicate()
82+
or
83+
// 6) toplevel is always alive.
84+
result instanceof TopLevel
7785
or
7886
// recursive cases
7987
result = aliveStep(alive())

ql/ql/test/queries/style/DeadCode/Foo.qll

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,3 +66,6 @@ private class CImpl1 extends AstNode { }
6666
final class CPublic1 = CImpl1;
6767

6868
private class CImpl2 extends AstNode { }
69+
70+
overlay[discard_entity]
71+
private predicate discard(@foo x) { any() }

0 commit comments

Comments
 (0)