Skip to content

Commit e03646a

Browse files
authored
Merge pull request #9737 from geoffw0/arithmetic
Swift: Add ArithmeticOperation.qll library
2 parents 8988a02 + f35ab7c commit e03646a

File tree

10 files changed

+259
-80
lines changed

10 files changed

+259
-80
lines changed
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
private import codeql.swift.elements.expr.Expr
2+
private import codeql.swift.elements.expr.BinaryExpr
3+
private import codeql.swift.elements.expr.PrefixUnaryExpr
4+
private import codeql.swift.elements.expr.DotSyntaxCallExpr
5+
6+
/**
7+
* An arithmetic operation, such as:
8+
* ```
9+
* a + b
10+
* ```
11+
*/
12+
class ArithmeticOperation extends Expr {
13+
ArithmeticOperation() {
14+
this instanceof BinaryArithmeticOperation or
15+
this instanceof UnaryArithmeticOperation
16+
}
17+
18+
/**
19+
* Gets an operand of this arithmetic operation.
20+
*/
21+
Expr getAnOperand() {
22+
result = this.(BinaryArithmeticOperation).getAnOperand()
23+
or
24+
result = this.(UnaryArithmeticOperation).getOperand()
25+
}
26+
}
27+
28+
/**
29+
* A binary arithmetic operation, such as:
30+
* ```
31+
* a + b
32+
* ```
33+
*/
34+
class BinaryArithmeticOperation extends BinaryExpr {
35+
BinaryArithmeticOperation() {
36+
this instanceof AddExpr or
37+
this instanceof SubExpr or
38+
this instanceof MulExpr or
39+
this instanceof DivExpr or
40+
this instanceof RemExpr
41+
}
42+
}
43+
44+
/**
45+
* An add expression.
46+
* ```
47+
* a + b
48+
* ```
49+
*/
50+
class AddExpr extends BinaryExpr {
51+
AddExpr() { this.getFunction().(DotSyntaxCallExpr).getStaticTarget().getName() = "+(_:_:)" }
52+
}
53+
54+
/**
55+
* A subtract expression.
56+
* ```
57+
* a - b
58+
* ```
59+
*/
60+
class SubExpr extends BinaryExpr {
61+
SubExpr() { this.getFunction().(DotSyntaxCallExpr).getStaticTarget().getName() = "-(_:_:)" }
62+
}
63+
64+
/**
65+
* A multiply expression.
66+
* ```
67+
* a * b
68+
* ```
69+
*/
70+
class MulExpr extends BinaryExpr {
71+
MulExpr() { this.getFunction().(DotSyntaxCallExpr).getStaticTarget().getName() = "*(_:_:)" }
72+
}
73+
74+
/**
75+
* A divide expression.
76+
* ```
77+
* a / b
78+
* ```
79+
*/
80+
class DivExpr extends BinaryExpr {
81+
DivExpr() { this.getFunction().(DotSyntaxCallExpr).getStaticTarget().getName() = "/(_:_:)" }
82+
}
83+
84+
/**
85+
* A remainder expression.
86+
* ```
87+
* a % b
88+
* ```
89+
*/
90+
class RemExpr extends BinaryExpr {
91+
RemExpr() { this.getFunction().(DotSyntaxCallExpr).getStaticTarget().getName() = "%(_:_:)" }
92+
}
93+
94+
/**
95+
* A unary arithmetic operation, such as:
96+
* ```
97+
* -a
98+
* ```
99+
*/
100+
class UnaryArithmeticOperation extends PrefixUnaryExpr {
101+
UnaryArithmeticOperation() { this instanceof UnaryMinusExpr }
102+
}
103+
104+
/**
105+
* A unary minus expression.
106+
* ```
107+
* -a
108+
* ```
109+
*/
110+
class UnaryMinusExpr extends PrefixUnaryExpr {
111+
UnaryMinusExpr() { this.getFunction().(DotSyntaxCallExpr).getStaticTarget().getName() = "-(_:)" }
112+
}

swift/ql/lib/codeql/swift/elements/expr/LogicalOperation.qll

Lines changed: 5 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -6,31 +6,19 @@ private import codeql.swift.elements.expr.DeclRefExpr
66
private import codeql.swift.elements.decl.ConcreteFuncDecl
77

88
private predicate unaryHasName(PrefixUnaryExpr e, string name) {
9-
e.getFunction()
10-
.(DotSyntaxCallExpr)
11-
.getFunction()
12-
.(DeclRefExpr)
13-
.getDecl()
14-
.(ConcreteFuncDecl)
15-
.getName() = name
9+
e.getFunction().(DotSyntaxCallExpr).getStaticTarget().getName() = name
1610
}
1711

1812
private predicate binaryHasName(BinaryExpr e, string name) {
19-
e.getFunction()
20-
.(DotSyntaxCallExpr)
21-
.getFunction()
22-
.(DeclRefExpr)
23-
.getDecl()
24-
.(ConcreteFuncDecl)
25-
.getName() = name
13+
e.getFunction().(DotSyntaxCallExpr).getStaticTarget().getName() = name
2614
}
2715

2816
class LogicalAndExpr extends BinaryExpr {
29-
LogicalAndExpr() { binaryHasName(this, "&&") }
17+
LogicalAndExpr() { binaryHasName(this, "&&(_:_:)") }
3018
}
3119

3220
class LogicalOrExpr extends BinaryExpr {
33-
LogicalOrExpr() { binaryHasName(this, "||") }
21+
LogicalOrExpr() { binaryHasName(this, "||(_:_:)") }
3422
}
3523

3624
class BinaryLogicalOperation extends BinaryExpr {
@@ -41,7 +29,7 @@ class BinaryLogicalOperation extends BinaryExpr {
4129
}
4230

4331
class NotExpr extends PrefixUnaryExpr {
44-
NotExpr() { unaryHasName(this, "!") }
32+
NotExpr() { unaryHasName(this, "!(_:)") }
4533
}
4634

4735
class UnaryLogicalOperation extends PrefixUnaryExpr {

swift/ql/lib/swift.qll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
/** Top-level import for the Swift language pack */
22

33
import codeql.swift.elements
4+
import codeql.swift.elements.expr.ArithmeticOperation
45
import codeql.swift.elements.expr.LogicalOperation
56
import codeql.swift.elements.decl.MethodDecl

swift/ql/test/library-tests/controlflow/graph/Cfg.expected

Lines changed: 71 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1670,19 +1670,29 @@ cfg.swift:
16701670
#-----| -> 2
16711671

16721672
# 185| ... call to <=(_:_:) ...
1673-
#-----| -> { ... }
1673+
#-----| false -> [false] ... call to &&(_:_:) ...
1674+
#-----| true -> { ... }
16741675

16751676
# 185| ... call to &&(_:_:) ...
16761677
#-----| exception -> exit m1(x:) (normal)
1677-
#-----| -> { ... }
1678+
#-----| false -> [false] ... call to &&(_:_:) ...
1679+
#-----| true -> { ... }
1680+
1681+
# 185| [false] ... call to &&(_:_:) ...
1682+
#-----| exception -> exit m1(x:) (normal)
1683+
#-----| false -> [false] ... call to &&(_:_:) ...
16781684

16791685
# 185| ... call to &&(_:_:) ...
16801686
#-----| exception -> exit m1(x:) (normal)
16811687
#-----| true -> print(_:separator:terminator:)
16821688
#-----| false -> print(_:separator:terminator:)
16831689

16841690
# 185| StmtCondition
1685-
#-----| -> &&(_:_:)
1691+
#-----| -> <=(_:_:)
1692+
1693+
# 185| [false] ... call to &&(_:_:) ...
1694+
#-----| exception -> exit m1(x:) (normal)
1695+
#-----| false -> print(_:separator:terminator:)
16861696

16871697
# 185| <=(_:_:)
16881698
#-----| -> Int.Type
@@ -1696,30 +1706,60 @@ cfg.swift:
16961706
# 185| 2
16971707
#-----| -> ... call to <=(_:_:) ...
16981708

1699-
# 185| &&(_:_:)
1700-
#-----| -> Bool.Type
1709+
# 185| x
1710+
#-----| -> 0
17011711

1702-
# 185| Bool.Type
1703-
#-----| -> call to &&(_:_:)
1712+
# 185| ... call to >(_:_:) ...
1713+
#-----| -> return ...
17041714

1705-
# 185| call to &&(_:_:)
1706-
#-----| -> <=(_:_:)
1715+
# 185| return ...
1716+
#-----| -> ... call to &&(_:_:) ...
17071717

17081718
# 185| { ... }
1709-
#-----| -> ... call to &&(_:_:) ...
1719+
#-----| -> >(_:_:)
17101720

1711-
# 185| &&(_:_:)
1712-
#-----| -> Bool.Type
1721+
# 185| >(_:_:)
1722+
#-----| -> Int.Type
17131723

1714-
# 185| Bool.Type
1715-
#-----| -> call to &&(_:_:)
1724+
# 185| Int.Type
1725+
#-----| -> call to >(_:_:)
17161726

1717-
# 185| call to &&(_:_:)
1718-
#-----| -> &&(_:_:)
1727+
# 185| call to >(_:_:)
1728+
#-----| -> x
17191729

1720-
# 185| { ... }
1730+
# 185| 0
1731+
#-----| -> ... call to >(_:_:) ...
1732+
1733+
# 185| call to ...
1734+
#-----| -> return ...
1735+
1736+
# 185| return ...
17211737
#-----| -> ... call to &&(_:_:) ...
17221738

1739+
# 185| { ... }
1740+
#-----| -> ==(_:_:)
1741+
1742+
# 185| (...)
1743+
#-----| -> call to ...
1744+
1745+
# 185| x
1746+
#-----| -> 5
1747+
1748+
# 185| ... call to ==(_:_:) ...
1749+
#-----| -> (...)
1750+
1751+
# 185| ==(_:_:)
1752+
#-----| -> Int.Type
1753+
1754+
# 185| Int.Type
1755+
#-----| -> call to ==(_:_:)
1756+
1757+
# 185| call to ==(_:_:)
1758+
#-----| -> x
1759+
1760+
# 185| 5
1761+
#-----| -> ... call to ==(_:_:) ...
1762+
17231763
# 186| print(_:separator:terminator:)
17241764
#-----| -> x is 1
17251765

@@ -2058,48 +2098,14 @@ cfg.swift:
20582098
# 224| if ... then { ... }
20592099
#-----| -> StmtCondition
20602100

2061-
# 224| !(_:)
2062-
#-----| -> Bool.Type
2063-
2064-
# 224| Bool.Type
2065-
#-----| -> call to !(_:)
2066-
2067-
# 224| call to !(_:)
2068-
#-----| -> true
2069-
20702101
# 224| StmtCondition
2071-
#-----| -> !(_:)
2102+
#-----| -> true
20722103

2073-
# 224| call to ...
2104+
# 224| [false] call to ...
20742105
#-----| false -> exit constant_condition() (normal)
2075-
#-----| true -> print(_:separator:terminator:)
20762106

20772107
# 224| true
2078-
#-----| -> call to ...
2079-
2080-
# 225| print(_:separator:terminator:)
2081-
#-----| -> Impossible
2082-
2083-
# 225| call to print(_:separator:terminator:)
2084-
#-----| -> exit constant_condition() (normal)
2085-
2086-
# 225| default separator
2087-
#-----| -> default terminator
2088-
2089-
# 225| default terminator
2090-
#-----| -> call to print(_:separator:terminator:)
2091-
2092-
# 225| (Any) ...
2093-
#-----| -> [...]
2094-
2095-
# 225| Impossible
2096-
#-----| -> (Any) ...
2097-
2098-
# 225| [...]
2099-
#-----| -> default separator
2100-
2101-
# 225| [...]
2102-
#-----| -> [...]
2108+
#-----| true -> [false] call to ...
21032109

21042110
# 229| empty_else(b:)
21052111
#-----| -> b
@@ -2197,7 +2203,7 @@ cfg.swift:
21972203
#-----| -> StmtCondition
21982204

21992205
# 238| StmtCondition
2200-
#-----| -> ||(_:_:)
2206+
#-----| -> b1
22012207

22022208
# 238| [false] (...)
22032209
#-----| false -> exit disjunct(b1:b2:) (normal)
@@ -2206,24 +2212,26 @@ cfg.swift:
22062212
#-----| true -> print(_:separator:terminator:)
22072213

22082214
# 238| b1
2209-
#-----| -> { ... }
2215+
#-----| true -> [true] ... call to ||(_:_:) ...
2216+
#-----| false -> { ... }
22102217

22112218
# 238| ... call to ||(_:_:) ...
22122219
#-----| exception -> exit disjunct(b1:b2:) (normal)
22132220
#-----| false -> [false] (...)
22142221
#-----| true -> [true] (...)
22152222

2216-
# 238| Bool.Type
2217-
#-----| -> call to ||(_:_:)
2223+
# 238| [true] ... call to ||(_:_:) ...
2224+
#-----| exception -> exit disjunct(b1:b2:) (normal)
2225+
#-----| true -> [true] (...)
22182226

2219-
# 238| call to ||(_:_:)
2220-
#-----| -> b1
2227+
# 238| b2
2228+
#-----| -> return ...
22212229

2222-
# 238| ||(_:_:)
2223-
#-----| -> Bool.Type
2230+
# 238| return ...
2231+
#-----| -> ... call to ||(_:_:) ...
22242232

22252233
# 238| { ... }
2226-
#-----| -> ... call to ||(_:_:) ...
2234+
#-----| -> b2
22272235

22282236
# 239| print(_:separator:terminator:)
22292237
#-----| -> b1 or b2
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
| arithmeticoperation.swift:6:6:6:10 | ... call to +(_:_:) ... | AddExpr, BinaryArithmeticOperation |
2+
| arithmeticoperation.swift:7:6:7:10 | ... call to -(_:_:) ... | BinaryArithmeticOperation, SubExpr |
3+
| arithmeticoperation.swift:8:6:8:10 | ... call to *(_:_:) ... | BinaryArithmeticOperation, MulExpr |
4+
| arithmeticoperation.swift:9:6:9:10 | ... call to /(_:_:) ... | BinaryArithmeticOperation, DivExpr |
5+
| arithmeticoperation.swift:10:6:10:10 | ... call to %(_:_:) ... | BinaryArithmeticOperation, RemExpr |
6+
| arithmeticoperation.swift:11:6:11:7 | call to ... | UnaryArithmeticOperation, UnaryMinusExpr |
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import swift
2+
3+
string describe(ArithmeticOperation e) {
4+
e instanceof BinaryArithmeticOperation and result = "BinaryArithmeticOperation"
5+
or
6+
e instanceof AddExpr and result = "AddExpr"
7+
or
8+
e instanceof SubExpr and result = "SubExpr"
9+
or
10+
e instanceof MulExpr and result = "MulExpr"
11+
or
12+
e instanceof DivExpr and result = "DivExpr"
13+
or
14+
e instanceof RemExpr and result = "RemExpr"
15+
or
16+
e instanceof UnaryArithmeticOperation and result = "UnaryArithmeticOperation"
17+
or
18+
e instanceof UnaryMinusExpr and result = "UnaryMinusExpr"
19+
}
20+
21+
from ArithmeticOperation e
22+
select e, concat(describe(e), ", ")

0 commit comments

Comments
 (0)