Skip to content

Commit c2beef1

Browse files
authored
Merge pull request #21765 from jketema/switch
C++: Fix join-order problem in `getNextSwitchCase`
2 parents 1ba9601 + 29dd56f commit c2beef1

2 files changed

Lines changed: 53 additions & 30 deletions

File tree

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
category: feature
3+
---
4+
* A new predicate `getSwitchCase` was added to the `SwitchStmt` class, which yields the `n`th `case` statement from a `switch` statement.

cpp/ql/lib/semmle/code/cpp/stmts/Stmt.qll

Lines changed: 49 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1412,9 +1412,9 @@ private int indexOfSwitchCaseRank(BlockStmt b, int rnk) {
14121412
* switch (i)
14131413
* {
14141414
* case 5:
1415-
* ...
1415+
* ...
14161416
* default:
1417-
* ...
1417+
* ...
14181418
* }
14191419
* ```
14201420
*/
@@ -1516,8 +1516,10 @@ class SwitchCase extends Stmt, @stmt_switch_case {
15161516
* which has result `default:`, which has no result.
15171517
*/
15181518
SwitchCase getNextSwitchCase() {
1519-
result.getSwitchStmt() = this.getSwitchStmt() and
1520-
result.getChildNum() = this.getChildNum() + 1
1519+
exists(SwitchStmt s, int n |
1520+
this = s.getSwitchCase(n) and
1521+
result = s.getSwitchCase(n + 1)
1522+
)
15211523
}
15221524

15231525
/**
@@ -1707,9 +1709,9 @@ class SwitchCase extends Stmt, @stmt_switch_case {
17071709
* switch (i)
17081710
* {
17091711
* case 5:
1710-
* ...
1712+
* ...
17111713
* default:
1712-
* ...
1714+
* ...
17131715
* }
17141716
* ```
17151717
*/
@@ -1731,9 +1733,9 @@ class DefaultCase extends SwitchCase {
17311733
* switch (i)
17321734
* {
17331735
* case 5:
1734-
* ...
1736+
* ...
17351737
* default:
1736-
* ...
1738+
* ...
17371739
* }
17381740
* ```
17391741
*/
@@ -1768,10 +1770,10 @@ class SwitchStmt extends ConditionalStmt, @stmt_switch {
17681770
* For example, for
17691771
* ```
17701772
* switch(i) {
1771-
* case 1:
1772-
* case 2:
1773+
* case 1:
1774+
* case 2:
17731775
* break;
1774-
* default:
1776+
* default:
17751777
* break;
17761778
* }
17771779
* ```
@@ -1790,20 +1792,20 @@ class SwitchStmt extends ConditionalStmt, @stmt_switch {
17901792
* For example, for
17911793
* ```
17921794
* switch(i) {
1793-
* case 1:
1794-
* case 2:
1795+
* case 1:
1796+
* case 2:
17951797
* break;
1796-
* default:
1798+
* default:
17971799
* break;
17981800
* }
17991801
* ```
18001802
* the result is
18011803
* ```
18021804
* {
1803-
* case 1:
1804-
* case 2:
1805+
* case 1:
1806+
* case 2:
18051807
* break;
1806-
* default:
1808+
* default:
18071809
* break;
18081810
* }
18091811
* ```
@@ -1816,36 +1818,53 @@ class SwitchStmt extends ConditionalStmt, @stmt_switch {
18161818
* For example, for
18171819
* ```
18181820
* switch(i) {
1819-
* case 1:
1820-
* case 2:
1821+
* case 1:
1822+
* case 2:
18211823
* break;
1822-
* default:
1824+
* default:
18231825
* break;
18241826
* }
18251827
* ```
18261828
* the results are `case 1:`, `case 2:` and `default:`.
18271829
*/
18281830
SwitchCase getASwitchCase() { switch_case(underlyingElement(this), _, unresolveElement(result)) }
18291831

1832+
/**
1833+
* Gets the `n`th 'switch case' statement of this 'switch' statement, where
1834+
* `n` is 0-based.
1835+
*
1836+
* For example, for
1837+
* ```
1838+
* switch(i) {
1839+
* case 5:
1840+
* case 6:
1841+
* default:
1842+
* } * ```
1843+
* 0 yields `case 5:`, 1 yields `case 6:`, and 2 yields `default:`.
1844+
*/
1845+
SwitchCase getSwitchCase(int n) {
1846+
switch_case(underlyingElement(this), n, unresolveElement(result))
1847+
}
1848+
18301849
/**
18311850
* Gets the 'default case' statement of this 'switch' statement,
18321851
* if any.
18331852
*
18341853
* For example, for
18351854
* ```
18361855
* switch(i) {
1837-
* case 1:
1838-
* case 2:
1856+
* case 1:
1857+
* case 2:
18391858
* break;
1840-
* default:
1859+
* default:
18411860
* break;
18421861
* }
18431862
* ```
18441863
* the result is `default:`, but there is no result for
18451864
* ```
18461865
* switch(i) {
1847-
* case 1:
1848-
* case 2:
1866+
* case 1:
1867+
* case 2:
18491868
* break;
18501869
* }
18511870
* ```
@@ -1858,18 +1877,18 @@ class SwitchStmt extends ConditionalStmt, @stmt_switch {
18581877
* For example, this holds for
18591878
* ```
18601879
* switch(i) {
1861-
* case 1:
1862-
* case 2:
1880+
* case 1:
1881+
* case 2:
18631882
* break;
1864-
* default:
1883+
* default:
18651884
* break;
18661885
* }
18671886
* ```
18681887
* but not for
18691888
* ```
18701889
* switch(i) {
1871-
* case 1:
1872-
* case 2:
1890+
* case 1:
1891+
* case 2:
18731892
* break;
18741893
* }
18751894
* ```

0 commit comments

Comments
 (0)