Skip to content

Commit 15e3892

Browse files
committed
Swift: Add support for overflow assignment operators.
1 parent 1d4925d commit 15e3892

File tree

3 files changed

+29
-5
lines changed

3 files changed

+29
-5
lines changed

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

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,18 @@ class Assignment extends Expr {
3737
result = this.(AssignExpr).getSource() or
3838
result = this.(AssignOperation).getRightOperand()
3939
}
40+
41+
/**
42+
* Holds if this assignment expression uses an overflow operator, that is,
43+
* an operator that truncates overflow rather than reporting an error.
44+
* ```
45+
* x &+= y
46+
* ```
47+
*/
48+
predicate hasOverflowOperator() {
49+
this.(AssignOperation).getOperator().getName() =
50+
["&*=(_:_:)", "&+=(_:_:)", "&-=(_:_:)", "&<<=(_:_:)", "&>>=(_:_:)"]
51+
}
4052
}
4153

4254
/**
@@ -95,10 +107,11 @@ abstract private class AssignBitwiseOperationEx extends BinaryExpr { }
95107
* An addition assignment expression:
96108
* ```
97109
* a += b
110+
* a &+= b
98111
* ```
99112
*/
100113
class AssignAddExpr extends AssignArithmeticOperationEx {
101-
AssignAddExpr() { this.getOperator().getName() = "+=(_:_:)" }
114+
AssignAddExpr() { this.getOperator().getName() = ["+=(_:_:)", "&+=(_:_:)"] }
102115

103116
override string toString() { result = "... += ..." }
104117
}
@@ -107,10 +120,11 @@ class AssignAddExpr extends AssignArithmeticOperationEx {
107120
* A subtraction assignment expression:
108121
* ```
109122
* a -= b
123+
* a &-= b
110124
* ```
111125
*/
112126
class AssignSubExpr extends AssignArithmeticOperationEx {
113-
AssignSubExpr() { this.getOperator().getName() = "-=(_:_:)" }
127+
AssignSubExpr() { this.getOperator().getName() = ["-=(_:_:)", "&-=(_:_:)"] }
114128

115129
override string toString() { result = "... -= ..." }
116130
}
@@ -119,10 +133,11 @@ class AssignSubExpr extends AssignArithmeticOperationEx {
119133
* A multiplication assignment expression:
120134
* ```
121135
* a *= b
136+
* a &*= b
122137
* ```
123138
*/
124139
class AssignMulExpr extends AssignArithmeticOperationEx {
125-
AssignMulExpr() { this.getOperator().getName() = "*=(_:_:)" }
140+
AssignMulExpr() { this.getOperator().getName() = ["*=(_:_:)", "&*=(_:_:)"] }
126141

127142
override string toString() { result = "... *= ..." }
128143
}
@@ -155,10 +170,11 @@ class AssignRemExpr extends AssignArithmeticOperationEx {
155170
* A left-shift assignment expression:
156171
* ```
157172
* a <<= b
173+
* a &<<= b
158174
* ```
159175
*/
160176
class AssignLShiftExpr extends AssignBitwiseOperationEx {
161-
AssignLShiftExpr() { this.getOperator().getName() = "<<=(_:_:)" }
177+
AssignLShiftExpr() { this.getOperator().getName() = ["<<=(_:_:)", "&<<=(_:_:)"] }
162178

163179
override string toString() { result = "... <<= ..." }
164180
}
@@ -167,10 +183,11 @@ class AssignLShiftExpr extends AssignBitwiseOperationEx {
167183
* A right-shift assignment expression:
168184
* ```
169185
* a >>= b
186+
* a &>>= b
170187
* ```
171188
*/
172189
class AssignRShiftExpr extends AssignBitwiseOperationEx {
173-
AssignRShiftExpr() { this.getOperator().getName() = ">>=(_:_:)" }
190+
AssignRShiftExpr() { this.getOperator().getName() = [">>=(_:_:)", "&>>=(_:_:)"] }
174191

175192
override string toString() { result = "... >>= ..." }
176193
}

swift/ql/test/library-tests/elements/expr/assignment/assignment.expected

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,9 @@
99
| assignment.swift:18:2:18:7 | ... ^= ... | AssignBitwiseOperation, AssignOperation, AssignXorExpr, Assignment | &... | 1 |
1010
| assignment.swift:19:2:19:8 | ... <<= ... | AssignBitwiseOperation, AssignLShiftExpr, AssignOperation, Assignment | &... | 1 |
1111
| assignment.swift:20:2:20:8 | ... >>= ... | AssignBitwiseOperation, AssignOperation, AssignRShiftExpr, Assignment | &... | 1 |
12+
| assignment.swift:23:2:23:8 | ... *= ... | AssignArithmeticOperation, AssignMulExpr, AssignOperation, Assignment, hasOverflowOperator | &... | 1 |
13+
| assignment.swift:24:2:24:8 | ... += ... | AssignAddExpr, AssignArithmeticOperation, AssignOperation, Assignment, hasOverflowOperator | &... | 1 |
14+
| assignment.swift:25:2:25:8 | ... -= ... | AssignArithmeticOperation, AssignOperation, AssignSubExpr, Assignment, hasOverflowOperator | &... | 1 |
15+
| assignment.swift:26:2:26:9 | ... <<= ... | AssignBitwiseOperation, AssignLShiftExpr, AssignOperation, Assignment, hasOverflowOperator | &... | 1 |
16+
| assignment.swift:27:2:27:9 | ... >>= ... | AssignBitwiseOperation, AssignOperation, AssignRShiftExpr, Assignment, hasOverflowOperator | &... | 1 |
1217
| assignment.swift:33:2:33:6 | ... = ... | AssignExpr, Assignment | y | z |

swift/ql/test/library-tests/elements/expr/assignment/assignment.ql

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ string describe(Expr e) {
3030
e instanceof AssignOrExpr and result = "AssignOrExpr"
3131
or
3232
e instanceof AssignXorExpr and result = "AssignXorExpr"
33+
or
34+
e.(Assignment).hasOverflowOperator() and result = "hasOverflowOperator"
3335
}
3436

3537
from Assignment e

0 commit comments

Comments
 (0)