mirror of
https://github.com/github/codeql.git
synced 2026-04-27 17:55:19 +02:00
Kotlin: Add support for more type operators
This commit is contained in:
@@ -667,6 +667,8 @@ case @expr.kind of
|
||||
| 74 = @errorexpr
|
||||
| 75 = @whenexpr
|
||||
| 76 = @getclassexpr
|
||||
| 77 = @safecastexpr
|
||||
| 78 = @notinstanceofexpr
|
||||
;
|
||||
|
||||
/** Holds if this `when` expression was written as an `if` expression. */
|
||||
|
||||
@@ -448,8 +448,12 @@ private module ControlFlowGraphImpl {
|
||||
or
|
||||
this instanceof CastExpr
|
||||
or
|
||||
this instanceof SafeCastExpr
|
||||
or
|
||||
this instanceof InstanceOfExpr and not this.(InstanceOfExpr).isPattern()
|
||||
or
|
||||
this instanceof NotInstanceOfExpr
|
||||
or
|
||||
this instanceof LocalVariableDeclExpr and
|
||||
not this = any(InstanceOfExpr ioe).getLocalVariableDeclExpr()
|
||||
or
|
||||
@@ -526,8 +530,12 @@ private module ControlFlowGraphImpl {
|
||||
or
|
||||
index = 0 and result = this.(CastExpr).getExpr()
|
||||
or
|
||||
index = 0 and result = this.(SafeCastExpr).getExpr()
|
||||
or
|
||||
index = 0 and result = this.(InstanceOfExpr).getExpr()
|
||||
or
|
||||
index = 0 and result = this.(NotInstanceOfExpr).getExpr()
|
||||
or
|
||||
index = 0 and result = this.(LocalVariableDeclExpr).getInit()
|
||||
or
|
||||
index = 0 and result = this.(RValue).getQualifier() and not result instanceof TypeAccess
|
||||
@@ -599,6 +607,8 @@ private module ControlFlowGraphImpl {
|
||||
or
|
||||
result = first(n.(InstanceOfExpr).getExpr())
|
||||
or
|
||||
result = first(n.(NotInstanceOfExpr).getExpr())
|
||||
or
|
||||
result = first(n.(SynchronizedStmt).getExpr())
|
||||
or
|
||||
result = n and
|
||||
|
||||
@@ -123,6 +123,18 @@ class CastConversionContext extends ConversionSite {
|
||||
override string kind() { result = "cast context" }
|
||||
}
|
||||
|
||||
class SafeCastConversionContext extends ConversionSite {
|
||||
SafeCastExpr c;
|
||||
|
||||
CastConversionContext() { this = c.getExpr() }
|
||||
|
||||
override Type getConversionTarget() { result = c.getType() }
|
||||
|
||||
override predicate isImplicit() { none() }
|
||||
|
||||
override string kind() { result = "safe cast context" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A numeric conversion. For example, `a * b` converts `a` and
|
||||
* `b` to have an appropriate numeric type.
|
||||
|
||||
@@ -1152,6 +1152,21 @@ class CastExpr extends Expr, @castexpr {
|
||||
override string getAPrimaryQlClass() { result = "CastExpr" }
|
||||
}
|
||||
|
||||
// TODO: Would this be better as a predicate on CastExpr?
|
||||
/** A safe cast expression. */
|
||||
class SafeCastExpr extends Expr, @safecastexpr {
|
||||
/** Gets the target type of this cast expression. */
|
||||
Expr getTypeExpr() { result.isNthChildOf(this, 0) }
|
||||
|
||||
/** Gets the expression to which the cast operator is applied. */
|
||||
Expr getExpr() { result.isNthChildOf(this, 1) }
|
||||
|
||||
/** Gets a printable representation of this expression. */
|
||||
override string toString() { result = "... as? ..." }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "SafeCastExpr" }
|
||||
}
|
||||
|
||||
/** A class instance creation expression. */
|
||||
class ClassInstanceExpr extends Expr, ConstructorCall, @classinstancexpr {
|
||||
/** Gets the number of arguments provided to the constructor of the class instance creation expression. */
|
||||
@@ -1442,6 +1457,28 @@ class InstanceOfExpr extends Expr, @instanceofexpr {
|
||||
override string getAPrimaryQlClass() { result = "InstanceOfExpr" }
|
||||
}
|
||||
|
||||
// TODO: Should this be desugared into instanceof.not()?
|
||||
// Note expressions/IrTypeOperatorCall.kt says:
|
||||
// NOT_INSTANCEOF, // TODO drop and replace with `INSTANCEOF<T>(x).not()`?
|
||||
/** An `instanceof` expression. */
|
||||
class NotInstanceOfExpr extends Expr, @notinstanceofexpr {
|
||||
/** Gets the expression on the left-hand side of the `!is` operator. */
|
||||
Expr getExpr() {
|
||||
result.isNthChildOf(this, 0)
|
||||
}
|
||||
|
||||
/** Gets the access to the type on the right-hand side of the `!is` operator. */
|
||||
Expr getTypeName() { result.isNthChildOf(this, 1) }
|
||||
|
||||
/** Gets the type this `!is` expression checks for. */
|
||||
RefType getCheckedType() { result = getTypeName().getType() }
|
||||
|
||||
/** Gets a printable representation of this expression. */
|
||||
override string toString() { result = "... !is ..." }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "NotInstanceOfExpr" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A local variable declaration expression.
|
||||
*
|
||||
|
||||
@@ -360,8 +360,8 @@ private predicate safeCast(Type fromtyp, Type totyp) {
|
||||
/**
|
||||
* A cast that can be ignored for the purpose of range analysis.
|
||||
*/
|
||||
private class SafeCastExpr extends CastExpr {
|
||||
SafeCastExpr() { safeCast(getExpr().getType(), getType()) }
|
||||
private class RangeAnalysisSafeCastExpr extends CastExpr {
|
||||
RangeAnalysisSafeCastExpr() { safeCast(getExpr().getType(), getType()) }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -382,7 +382,7 @@ private predicate typeBound(Type typ, int lowerbound, int upperbound) {
|
||||
*/
|
||||
private class NarrowingCastExpr extends CastExpr {
|
||||
NarrowingCastExpr() {
|
||||
not this instanceof SafeCastExpr and
|
||||
not this instanceof RangeAnalysisSafeCastExpr and
|
||||
typeBound(getType(), _, _)
|
||||
}
|
||||
|
||||
@@ -412,7 +412,7 @@ private predicate boundFlowStep(Expr e2, Expr e1, int delta, boolean upper) {
|
||||
valueFlowStep(e2, e1, delta) and
|
||||
(upper = true or upper = false)
|
||||
or
|
||||
e2.(SafeCastExpr).getExpr() = e1 and
|
||||
e2.(RangeAnalysisSafeCastExpr).getExpr() = e1 and
|
||||
delta = 0 and
|
||||
(upper = true or upper = false)
|
||||
or
|
||||
|
||||
@@ -54,8 +54,15 @@
|
||||
| exprs.kt:40:5:40:22 | b6 | LocalVariableDeclExpr |
|
||||
| exprs.kt:40:14:40:15 | i1 | VarAccess |
|
||||
| exprs.kt:40:14:40:22 | ...instanceof... | InstanceOfExpr |
|
||||
| exprs.kt:40:14:40:22 | int | TypeAccess |
|
||||
| exprs.kt:41:5:41:23 | b7 | LocalVariableDeclExpr |
|
||||
| exprs.kt:41:14:41:15 | i1 | VarAccess |
|
||||
| exprs.kt:41:14:41:23 | ... !is ... | NotInstanceOfExpr |
|
||||
| exprs.kt:41:14:41:23 | int | TypeAccess |
|
||||
| exprs.kt:42:5:42:26 | b8 | LocalVariableDeclExpr |
|
||||
| exprs.kt:42:14:42:15 | b7 | VarAccess |
|
||||
| exprs.kt:42:14:42:26 | (...)... | CastExpr |
|
||||
| exprs.kt:42:14:42:26 | boolean | TypeAccess |
|
||||
| exprs.kt:43:5:43:35 | str1 | LocalVariableDeclExpr |
|
||||
| exprs.kt:43:25:43:34 | string lit | StringLiteral |
|
||||
| exprs.kt:44:5:44:36 | str2 | LocalVariableDeclExpr |
|
||||
@@ -74,4 +81,3 @@
|
||||
| exprs.kt:53:9:53:18 | n | VarAccess |
|
||||
| exprs.kt:54:27:54:31 | new C(...) | ClassInstanceExpr |
|
||||
| exprs.kt:54:29:54:30 | 42 | IntegerLiteral |
|
||||
| file://:0:0:0:0 | int | TypeAccess |
|
||||
|
||||
Reference in New Issue
Block a user