Skip to content

Commit 4fcf3fb

Browse files
committed
Java: Make loop classes extend LoopStmt and use getBody instead of getStmt.
1 parent 6f40ac1 commit 4fcf3fb

File tree

5 files changed

+70
-56
lines changed

5 files changed

+70
-56
lines changed

java/ql/lib/semmle/code/java/ControlFlowGraph.qll

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1427,7 +1427,7 @@ private module ControlFlowGraphImpl {
14271427
condentry = first(for.getCondition())
14281428
or
14291429
// ...or the body if the for doesn't include a condition.
1430-
not exists(for.getCondition()) and condentry = first(for.getStmt())
1430+
not exists(for.getCondition()) and condentry = first(for.getBody())
14311431
|
14321432
// From the entry point, which is the for statement itself, control goes to either the first init expression...
14331433
n.asStmt() = for and result = first(for.getInit(0)) and completion = NormalCompletion()
@@ -1448,7 +1448,7 @@ private module ControlFlowGraphImpl {
14481448
// The true-successor of the condition is the body of the for loop.
14491449
last(for.getCondition(), n, completion) and
14501450
completion = BooleanCompletion(true, _) and
1451-
result = first(for.getStmt())
1451+
result = first(for.getBody())
14521452
or
14531453
// The updates execute sequentially, after which control is transferred to the condition.
14541454
exists(int i | last(for.getUpdate(i), n, completion) and completion = NormalCompletion() |
@@ -1458,7 +1458,7 @@ private module ControlFlowGraphImpl {
14581458
)
14591459
or
14601460
// The back edge of the loop: control goes to either the first update or the condition if no updates exist.
1461-
last(for.getStmt(), n, completion) and
1461+
last(for.getBody(), n, completion) and
14621462
continues(completion, for) and
14631463
(
14641464
result = first(for.getUpdate(0))
@@ -1479,11 +1479,11 @@ private module ControlFlowGraphImpl {
14791479
or
14801480
// ...and then control goes to the body of the loop.
14811481
n.asExpr() = for.getVariable() and
1482-
result = first(for.getStmt()) and
1482+
result = first(for.getBody()) and
14831483
completion = NormalCompletion()
14841484
or
14851485
// Finally, the back edge of the loop goes to reassign the variable.
1486-
last(for.getStmt(), n, completion) and
1486+
last(for.getBody(), n, completion) and
14871487
continues(completion, for) and
14881488
result.asExpr() = for.getVariable()
14891489
)
@@ -1492,7 +1492,7 @@ private module ControlFlowGraphImpl {
14921492
result = first(n.asStmt().(WhileStmt).getCondition()) and completion = NormalCompletion()
14931493
or
14941494
// ...and do-while loops start at the body.
1495-
result = first(n.asStmt().(DoStmt).getStmt()) and completion = NormalCompletion()
1495+
result = first(n.asStmt().(DoStmt).getBody()) and completion = NormalCompletion()
14961496
or
14971497
exists(LoopStmt loop | loop instanceof WhileStmt or loop instanceof DoStmt |
14981498
// Control goes from the condition via a true-completion to the body...

java/ql/lib/semmle/code/java/PrettyPrintAst.qll

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -577,7 +577,7 @@ private class PpForStmt extends PpAst, ForStmt {
577577
or
578578
i = 1 + this.lastUpdateIndex() and result = ")"
579579
or
580-
i = 2 + this.lastUpdateIndex() and result = " " and this.getStmt() instanceof BlockStmt
580+
i = 2 + this.lastUpdateIndex() and result = " " and this.getBody() instanceof BlockStmt
581581
}
582582

583583
private int lastInitIndex() { result = 3 + 2 * max(int j | exists(this.getInit(j))) }
@@ -587,7 +587,7 @@ private class PpForStmt extends PpAst, ForStmt {
587587
}
588588

589589
override predicate newline(int i) {
590-
i = 2 + this.lastUpdateIndex() and not this.getStmt() instanceof BlockStmt
590+
i = 2 + this.lastUpdateIndex() and not this.getBody() instanceof BlockStmt
591591
}
592592

593593
override PpAst getChild(int i) {
@@ -599,11 +599,11 @@ private class PpForStmt extends PpAst, ForStmt {
599599
or
600600
exists(int j | result = this.getUpdate(j) and i = 4 + this.lastInitIndex() + 2 * j)
601601
or
602-
i = 3 + this.lastUpdateIndex() and result = this.getStmt()
602+
i = 3 + this.lastUpdateIndex() and result = this.getBody()
603603
}
604604

605605
override predicate indents(int i) {
606-
i = 3 + this.lastUpdateIndex() and not this.getStmt() instanceof BlockStmt
606+
i = 3 + this.lastUpdateIndex() and not this.getBody() instanceof BlockStmt
607607
}
608608
}
609609

@@ -616,7 +616,7 @@ private class PpEnhancedForStmt extends PpAst, EnhancedForStmt {
616616
i = 4 and result = " : "
617617
or
618618
i = 6 and
619-
if this.getStmt() instanceof BlockStmt then result = ") " else result = ")"
619+
if this.getBody() instanceof BlockStmt then result = ") " else result = ")"
620620
}
621621

622622
override PpAst getChild(int i) {
@@ -626,10 +626,10 @@ private class PpEnhancedForStmt extends PpAst, EnhancedForStmt {
626626
or
627627
i = 5 and result = this.getExpr()
628628
or
629-
i = 7 and result = this.getStmt()
629+
i = 7 and result = this.getBody()
630630
}
631631

632-
override predicate indents(int i) { i = 7 and not this.getStmt() instanceof BlockStmt }
632+
override predicate indents(int i) { i = 7 and not this.getBody() instanceof BlockStmt }
633633
}
634634

635635
private class PpWhileStmt extends PpAst, WhileStmt {
@@ -638,40 +638,40 @@ private class PpWhileStmt extends PpAst, WhileStmt {
638638
or
639639
i = 2 and result = ")"
640640
or
641-
i = 3 and result = " " and this.getStmt() instanceof BlockStmt
641+
i = 3 and result = " " and this.getBody() instanceof BlockStmt
642642
}
643643

644-
override predicate newline(int i) { i = 3 and not this.getStmt() instanceof BlockStmt }
644+
override predicate newline(int i) { i = 3 and not this.getBody() instanceof BlockStmt }
645645

646646
override PpAst getChild(int i) {
647647
i = 1 and result = this.getCondition()
648648
or
649-
i = 4 and result = this.getStmt()
649+
i = 4 and result = this.getBody()
650650
}
651651

652-
override predicate indents(int i) { i = 4 and not this.getStmt() instanceof BlockStmt }
652+
override predicate indents(int i) { i = 4 and not this.getBody() instanceof BlockStmt }
653653
}
654654

655655
private class PpDoStmt extends PpAst, DoStmt {
656656
override string getPart(int i) {
657657
i = 0 and result = "do"
658658
or
659-
i in [1, 3] and result = " " and this.getStmt() instanceof BlockStmt
659+
i in [1, 3] and result = " " and this.getBody() instanceof BlockStmt
660660
or
661661
i = 4 and result = "while ("
662662
or
663663
i = 6 and result = ");"
664664
}
665665

666-
override predicate newline(int i) { i in [1, 3] and not this.getStmt() instanceof BlockStmt }
666+
override predicate newline(int i) { i in [1, 3] and not this.getBody() instanceof BlockStmt }
667667

668668
override PpAst getChild(int i) {
669-
i = 2 and result = this.getStmt()
669+
i = 2 and result = this.getBody()
670670
or
671671
i = 5 and result = this.getCondition()
672672
}
673673

674-
override predicate indents(int i) { i = 2 and not this.getStmt() instanceof BlockStmt }
674+
override predicate indents(int i) { i = 2 and not this.getBody() instanceof BlockStmt }
675675
}
676676

677677
private class PpTryStmt extends PpAst, TryStmt {

java/ql/lib/semmle/code/java/Statement.qll

Lines changed: 45 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ class IfStmt extends ConditionalStmt, @ifstmt {
140140
}
141141

142142
/** A `for` loop. */
143-
class ForStmt extends ConditionalStmt, @forstmt {
143+
class ForStmt extends ConditionalStmt, LoopStmtImpl, @forstmt {
144144
/**
145145
* Gets an initializer expression of the loop.
146146
*
@@ -167,8 +167,15 @@ class ForStmt extends ConditionalStmt, @forstmt {
167167
index = result.getIndex() - 3
168168
}
169169

170+
/**
171+
* DEPRECATED: Use getBody() instead.
172+
*
173+
* Gets the body of this `for` loop.
174+
*/
175+
deprecated Stmt getStmt() { result.getParent() = this and result.getIndex() = 2 }
176+
170177
/** Gets the body of this `for` loop. */
171-
Stmt getStmt() { result.getParent() = this and result.getIndex() = 2 }
178+
override Stmt getBody() { result.getParent() = this and result.getIndex() = 2 }
172179

173180
/**
174181
* Gets a variable that is used as an iteration variable: it is defined,
@@ -191,7 +198,7 @@ class ForStmt extends ConditionalStmt, @forstmt {
191198
this.getCondition().getAChildExpr*() = result.getAnAccess()
192199
}
193200

194-
override string pp() { result = "for (...;...;...) " + this.getStmt().pp() }
201+
override string pp() { result = "for (...;...;...) " + this.getBody().pp() }
195202

196203
override string toString() { result = "for (...;...;...)" }
197204

@@ -201,17 +208,24 @@ class ForStmt extends ConditionalStmt, @forstmt {
201208
}
202209

203210
/** An enhanced `for` loop. (Introduced in Java 5.) */
204-
class EnhancedForStmt extends Stmt, @enhancedforstmt {
211+
class EnhancedForStmt extends LoopStmtImpl, @enhancedforstmt {
205212
/** Gets the local variable declaration expression of this enhanced `for` loop. */
206213
LocalVariableDeclExpr getVariable() { result.getParent() = this }
207214

208215
/** Gets the expression over which this enhanced `for` loop iterates. */
209216
Expr getExpr() { result.isNthChildOf(this, 1) }
210217

218+
/**
219+
* DEPRECATED: Use getBody() instead.
220+
*
221+
* Gets the body of this enhanced `for` loop.
222+
*/
223+
deprecated Stmt getStmt() { result.getParent() = this }
224+
211225
/** Gets the body of this enhanced `for` loop. */
212-
Stmt getStmt() { result.getParent() = this }
226+
override Stmt getBody() { result.getParent() = this }
213227

214-
override string pp() { result = "for (... : ...) " + this.getStmt().pp() }
228+
override string pp() { result = "for (... : ...) " + this.getBody().pp() }
215229

216230
override string toString() { result = "for (... : ...)" }
217231

@@ -221,14 +235,21 @@ class EnhancedForStmt extends Stmt, @enhancedforstmt {
221235
}
222236

223237
/** A `while` loop. */
224-
class WhileStmt extends ConditionalStmt, @whilestmt {
238+
class WhileStmt extends ConditionalStmt, LoopStmtImpl, @whilestmt {
225239
/** Gets the boolean condition of this `while` loop. */
226240
override Expr getCondition() { result.getParent() = this }
227241

242+
/**
243+
* DEPRECATED: Use getBody() instead.
244+
*
245+
* Gets the body of this `while` loop.
246+
*/
247+
deprecated Stmt getStmt() { result.getParent() = this }
248+
228249
/** Gets the body of this `while` loop. */
229-
Stmt getStmt() { result.getParent() = this }
250+
override Stmt getBody() { result.getParent() = this }
230251

231-
override string pp() { result = "while (...) " + this.getStmt().pp() }
252+
override string pp() { result = "while (...) " + this.getBody().pp() }
232253

233254
override string toString() { result = "while (...)" }
234255

@@ -238,14 +259,21 @@ class WhileStmt extends ConditionalStmt, @whilestmt {
238259
}
239260

240261
/** A `do` loop. */
241-
class DoStmt extends ConditionalStmt, @dostmt {
262+
class DoStmt extends ConditionalStmt, LoopStmtImpl, @dostmt {
242263
/** Gets the condition of this `do` loop. */
243264
override Expr getCondition() { result.getParent() = this }
244265

266+
/**
267+
* DEPRECATED: Use getBody() instead.
268+
*
269+
* Gets the body of this `do` loop.
270+
*/
271+
deprecated Stmt getStmt() { result.getParent() = this }
272+
245273
/** Gets the body of this `do` loop. */
246-
Stmt getStmt() { result.getParent() = this }
274+
override Stmt getBody() { result.getParent() = this }
247275

248-
override string pp() { result = "do " + this.getStmt().pp() + " while (...)" }
276+
override string pp() { result = "do " + this.getBody().pp() + " while (...)" }
249277

250278
override string toString() { result = "do ... while (...)" }
251279

@@ -258,30 +286,16 @@ class DoStmt extends ConditionalStmt, @dostmt {
258286
* A loop statement, including `for`, enhanced `for`,
259287
* `while` and `do` statements.
260288
*/
261-
class LoopStmt extends Stmt {
262-
LoopStmt() {
263-
this instanceof ForStmt or
264-
this instanceof EnhancedForStmt or
265-
this instanceof WhileStmt or
266-
this instanceof DoStmt
267-
}
268-
289+
abstract private class LoopStmtImpl extends Stmt {
269290
/** Gets the body of this loop statement. */
270-
Stmt getBody() {
271-
result = this.(ForStmt).getStmt() or
272-
result = this.(EnhancedForStmt).getStmt() or
273-
result = this.(WhileStmt).getStmt() or
274-
result = this.(DoStmt).getStmt()
275-
}
291+
abstract Stmt getBody();
276292

277293
/** Gets the boolean condition of this loop statement. */
278-
Expr getCondition() {
279-
result = this.(ForStmt).getCondition() or
280-
result = this.(WhileStmt).getCondition() or
281-
result = this.(DoStmt).getCondition()
282-
}
294+
Expr getCondition() { none() }
283295
}
284296

297+
final class LoopStmt = LoopStmtImpl;
298+
285299
/** A `try` statement. */
286300
class TryStmt extends Stmt, @trystmt {
287301
/** Gets the block of the `try` statement. */

java/ql/lib/semmle/code/java/security/internal/ArraySizing.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ class PointlessLoop extends WhileStmt {
4949
this.getCondition().(BooleanLiteral).getBooleanValue() = true and
5050
// The only `break` must be the last statement.
5151
forall(BreakStmt break | break.getTarget() = this |
52-
this.getStmt().(BlockStmt).getLastStmt() = break
52+
this.getBody().(BlockStmt).getLastStmt() = break
5353
) and
5454
// No `continue` statements.
5555
not exists(ContinueStmt continue | continue.getTarget() = this)

java/ql/src/Likely Bugs/Termination/SpinOnField.ql

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,12 @@ class EmptyLoop extends Stmt {
3737
exists(ForStmt stmt | stmt = this |
3838
not exists(stmt.getAnInit()) and
3939
not exists(stmt.getAnUpdate()) and
40-
stmt.getStmt() instanceof Empty
40+
stmt.getBody() instanceof Empty
4141
)
4242
or
43-
this.(WhileStmt).getStmt() instanceof Empty
43+
this.(WhileStmt).getBody() instanceof Empty
4444
or
45-
this.(DoStmt).getStmt() instanceof Empty
45+
this.(DoStmt).getBody() instanceof Empty
4646
}
4747

4848
Expr getCondition() {

0 commit comments

Comments
 (0)