Swift: Add support for overflow assignment operators.

This commit is contained in:
Geoffrey White
2023-02-23 13:57:50 +00:00
parent 1d4925d7af
commit 15e3892b03
3 changed files with 29 additions and 5 deletions

View File

@@ -37,6 +37,18 @@ class Assignment extends Expr {
result = this.(AssignExpr).getSource() or
result = this.(AssignOperation).getRightOperand()
}
/**
* Holds if this assignment expression uses an overflow operator, that is,
* an operator that truncates overflow rather than reporting an error.
* ```
* x &+= y
* ```
*/
predicate hasOverflowOperator() {
this.(AssignOperation).getOperator().getName() =
["&*=(_:_:)", "&+=(_:_:)", "&-=(_:_:)", "&<<=(_:_:)", "&>>=(_:_:)"]
}
}
/**
@@ -95,10 +107,11 @@ abstract private class AssignBitwiseOperationEx extends BinaryExpr { }
* An addition assignment expression:
* ```
* a += b
* a &+= b
* ```
*/
class AssignAddExpr extends AssignArithmeticOperationEx {
AssignAddExpr() { this.getOperator().getName() = "+=(_:_:)" }
AssignAddExpr() { this.getOperator().getName() = ["+=(_:_:)", "&+=(_:_:)"] }
override string toString() { result = "... += ..." }
}
@@ -107,10 +120,11 @@ class AssignAddExpr extends AssignArithmeticOperationEx {
* A subtraction assignment expression:
* ```
* a -= b
* a &-= b
* ```
*/
class AssignSubExpr extends AssignArithmeticOperationEx {
AssignSubExpr() { this.getOperator().getName() = "-=(_:_:)" }
AssignSubExpr() { this.getOperator().getName() = ["-=(_:_:)", "&-=(_:_:)"] }
override string toString() { result = "... -= ..." }
}
@@ -119,10 +133,11 @@ class AssignSubExpr extends AssignArithmeticOperationEx {
* A multiplication assignment expression:
* ```
* a *= b
* a &*= b
* ```
*/
class AssignMulExpr extends AssignArithmeticOperationEx {
AssignMulExpr() { this.getOperator().getName() = "*=(_:_:)" }
AssignMulExpr() { this.getOperator().getName() = ["*=(_:_:)", "&*=(_:_:)"] }
override string toString() { result = "... *= ..." }
}
@@ -155,10 +170,11 @@ class AssignRemExpr extends AssignArithmeticOperationEx {
* A left-shift assignment expression:
* ```
* a <<= b
* a &<<= b
* ```
*/
class AssignLShiftExpr extends AssignBitwiseOperationEx {
AssignLShiftExpr() { this.getOperator().getName() = "<<=(_:_:)" }
AssignLShiftExpr() { this.getOperator().getName() = ["<<=(_:_:)", "&<<=(_:_:)"] }
override string toString() { result = "... <<= ..." }
}
@@ -167,10 +183,11 @@ class AssignLShiftExpr extends AssignBitwiseOperationEx {
* A right-shift assignment expression:
* ```
* a >>= b
* a &>>= b
* ```
*/
class AssignRShiftExpr extends AssignBitwiseOperationEx {
AssignRShiftExpr() { this.getOperator().getName() = ">>=(_:_:)" }
AssignRShiftExpr() { this.getOperator().getName() = [">>=(_:_:)", "&>>=(_:_:)"] }
override string toString() { result = "... >>= ..." }
}

View File

@@ -9,4 +9,9 @@
| assignment.swift:18:2:18:7 | ... ^= ... | AssignBitwiseOperation, AssignOperation, AssignXorExpr, Assignment | &... | 1 |
| assignment.swift:19:2:19:8 | ... <<= ... | AssignBitwiseOperation, AssignLShiftExpr, AssignOperation, Assignment | &... | 1 |
| assignment.swift:20:2:20:8 | ... >>= ... | AssignBitwiseOperation, AssignOperation, AssignRShiftExpr, Assignment | &... | 1 |
| assignment.swift:23:2:23:8 | ... *= ... | AssignArithmeticOperation, AssignMulExpr, AssignOperation, Assignment, hasOverflowOperator | &... | 1 |
| assignment.swift:24:2:24:8 | ... += ... | AssignAddExpr, AssignArithmeticOperation, AssignOperation, Assignment, hasOverflowOperator | &... | 1 |
| assignment.swift:25:2:25:8 | ... -= ... | AssignArithmeticOperation, AssignOperation, AssignSubExpr, Assignment, hasOverflowOperator | &... | 1 |
| assignment.swift:26:2:26:9 | ... <<= ... | AssignBitwiseOperation, AssignLShiftExpr, AssignOperation, Assignment, hasOverflowOperator | &... | 1 |
| assignment.swift:27:2:27:9 | ... >>= ... | AssignBitwiseOperation, AssignOperation, AssignRShiftExpr, Assignment, hasOverflowOperator | &... | 1 |
| assignment.swift:33:2:33:6 | ... = ... | AssignExpr, Assignment | y | z |

View File

@@ -30,6 +30,8 @@ string describe(Expr e) {
e instanceof AssignOrExpr and result = "AssignOrExpr"
or
e instanceof AssignXorExpr and result = "AssignXorExpr"
or
e.(Assignment).hasOverflowOperator() and result = "hasOverflowOperator"
}
from Assignment e