mirror of
https://github.com/github/codeql.git
synced 2025-12-24 04:36:35 +01:00
Kotlin: Extract missing arguments of enum constructor calls
This commit is contained in:
@@ -1868,12 +1868,13 @@ open class KotlinFileExtractor(
|
||||
extractStaticTypeAccessQualifierUnchecked(overriddenCallTarget.parent, id, locId, enclosingCallable, enclosingStmt)
|
||||
}
|
||||
|
||||
extractDefaultsCallArguments(id, overriddenCallTarget, enclosingCallable, enclosingStmt, valueArguments, dispatchReceiver, extensionReceiver)
|
||||
extractDefaultsCallArguments(id, overriddenCallTarget, locId, enclosingCallable, enclosingStmt, valueArguments, dispatchReceiver, extensionReceiver)
|
||||
}
|
||||
|
||||
private fun extractDefaultsCallArguments(
|
||||
id: Label<out DbExprparent>,
|
||||
callTarget: IrFunction,
|
||||
locId: Label<DbLocation>,
|
||||
enclosingCallable: Label<out DbCallable>,
|
||||
enclosingStmt: Label<out DbStmt>,
|
||||
valueArguments: List<IrExpression?>,
|
||||
@@ -1900,7 +1901,7 @@ open class KotlinFileExtractor(
|
||||
IrConstImpl.defaultValueForType(0, 0, getDefaultsMethodLastArgType(callTarget))
|
||||
)
|
||||
|
||||
extractCallValueArguments(id, valueArgsWithDummies + extraArgs, enclosingStmt, enclosingCallable, nextIdx, extractVarargAsArray = true)
|
||||
extractCallValueArguments(id, valueArgsWithDummies + extraArgs, callTarget, locId, enclosingStmt, enclosingCallable, nextIdx, extractVarargAsArray = true)
|
||||
}
|
||||
|
||||
private fun getFunctionInvokeMethod(typeArgs: List<IrTypeArgument>): IrFunction? {
|
||||
@@ -2022,7 +2023,7 @@ open class KotlinFileExtractor(
|
||||
childIdx,
|
||||
enclosingStmt,
|
||||
valueArguments.size,
|
||||
{ argParent, idxOffset -> extractCallValueArguments(argParent, valueArguments, enclosingStmt, enclosingCallable, idxOffset) },
|
||||
{ argParent, idxOffset -> extractCallValueArguments(argParent, valueArguments, syntacticCallTarget, locId, enclosingStmt, enclosingCallable, idxOffset) },
|
||||
dispatchReceiver?.type,
|
||||
dispatchReceiver?.let { { callId -> extractExpressionExpr(dispatchReceiver, enclosingCallable, callId, -1, enclosingStmt) } },
|
||||
extensionReceiver?.let { { argParent -> extractExpressionExpr(extensionReceiver, enclosingCallable, argParent, 0, enclosingStmt) } },
|
||||
@@ -2116,19 +2117,38 @@ open class KotlinFileExtractor(
|
||||
this is IrEnumEntry
|
||||
|
||||
|
||||
private fun extractCallValueArguments(callId: Label<out DbExprparent>, call: IrFunctionAccessExpression, enclosingStmt: Label<out DbStmt>, enclosingCallable: Label<out DbCallable>, idxOffset: Int) =
|
||||
extractCallValueArguments(callId, (0 until call.valueArgumentsCount).map { call.getValueArgument(it) }, enclosingStmt, enclosingCallable, idxOffset)
|
||||
private fun extractCallValueArguments(callId: Label<out DbExprparent>, call: IrFunctionAccessExpression, callTarget: IrFunction, fallbackLocation: Label<DbLocation>, enclosingStmt: Label<out DbStmt>, enclosingCallable: Label<out DbCallable>, idxOffset: Int) =
|
||||
extractCallValueArguments(callId, (0 until call.valueArgumentsCount).map { call.getValueArgument(it) }, callTarget, fallbackLocation, enclosingStmt, enclosingCallable, idxOffset)
|
||||
|
||||
private fun extractCallValueArguments(callId: Label<out DbExprparent>, valueArguments: List<IrExpression?>, enclosingStmt: Label<out DbStmt>, enclosingCallable: Label<out DbCallable>, idxOffset: Int, extractVarargAsArray: Boolean = false) {
|
||||
private fun extractCallValueArguments(callId: Label<out DbExprparent>, valueArguments: List<IrExpression?>, callTarget: IrFunction, fallbackLocation: Label<DbLocation>, enclosingStmt: Label<out DbStmt>, enclosingCallable: Label<out DbCallable>, idxOffset: Int, extractVarargAsArray: Boolean = false) {
|
||||
var i = 0
|
||||
valueArguments.forEach { arg ->
|
||||
if(arg != null) {
|
||||
if (arg != null) {
|
||||
if (arg is IrVararg && !extractVarargAsArray) {
|
||||
arg.elements.forEachIndexed { varargNo, vararg -> extractVarargElement(vararg, enclosingCallable, callId, i + idxOffset + varargNo, enclosingStmt) }
|
||||
i += arg.elements.size
|
||||
} else {
|
||||
extractExpressionExpr(arg, enclosingCallable, callId, (i++) + idxOffset, enclosingStmt)
|
||||
}
|
||||
} else {
|
||||
val realCallTarget = callTarget.target.realOverrideTarget
|
||||
|
||||
// Generated constructor calls to kotlin.Enum have no arguments in IR, but the constructor takes two parameters.
|
||||
if (realCallTarget is IrConstructor &&
|
||||
realCallTarget.parentClassOrNull?.symbol == pluginContext.irBuiltIns.enumClass &&
|
||||
realCallTarget.valueParameters.size == 2 &&
|
||||
i < realCallTarget.valueParameters.size) {
|
||||
|
||||
if (i == 0 && realCallTarget.valueParameters[i].type == pluginContext.irBuiltIns.stringType) {
|
||||
|
||||
val id = extractNull(pluginContext.irBuiltIns.stringType, fallbackLocation, callId, (i++) + idxOffset, enclosingCallable, enclosingStmt)
|
||||
tw.writeCompiler_generated(id, CompilerGeneratedKinds.ENUM_CONSTRUCTOR_ARGUMENT.kind)
|
||||
} else if (i == 1 && realCallTarget.valueParameters[i].type == pluginContext.irBuiltIns.intType) {
|
||||
|
||||
val id = extractConstantInteger(0, fallbackLocation, callId, (i++) + idxOffset, enclosingCallable, enclosingStmt)
|
||||
tw.writeCompiler_generated(id, CompilerGeneratedKinds.ENUM_CONSTRUCTOR_ARGUMENT.kind)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3067,11 +3087,11 @@ open class KotlinFileExtractor(
|
||||
// which have null arguments even though the parameters don't give default values.
|
||||
val id = if (e !is IrEnumConstructorCall && callUsesDefaultArguments(e.symbol.owner, valueArgs)) {
|
||||
extractNewExpr(getDefaultsMethodLabel(e.symbol.owner).cast(), type, locId, parent, idx, callable, enclosingStmt).also {
|
||||
extractDefaultsCallArguments(it, e.symbol.owner, callable, enclosingStmt, valueArgs, null, null)
|
||||
extractDefaultsCallArguments(it, e.symbol.owner, locId, callable, enclosingStmt, valueArgs, null, null)
|
||||
}
|
||||
} else {
|
||||
extractNewExpr(e.symbol.owner, eType.arguments, type, locId, parent, idx, callable, enclosingStmt).also {
|
||||
extractCallValueArguments(it, e, enclosingStmt, callable, 0)
|
||||
extractCallValueArguments(it, e, e.symbol.owner, locId, enclosingStmt, callable, 0)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3396,6 +3416,14 @@ open class KotlinFileExtractor(
|
||||
extractExprContext(it, locId, callable, enclosingStmt)
|
||||
}
|
||||
|
||||
private fun extractNull(t: IrType, locId: Label<DbLocation>, parent: Label<out DbExprparent>, idx: Int, callable: Label<out DbCallable>, enclosingStmt: Label<out DbStmt>) =
|
||||
tw.getFreshIdLabel<DbNullliteral>().also {
|
||||
val type = useType(t)
|
||||
tw.writeExprs_nullliteral(it, type.javaResult.id, parent, idx)
|
||||
tw.writeExprsKotlinType(it, type.kotlinResult.id)
|
||||
extractExprContext(it, locId, callable, enclosingStmt)
|
||||
}
|
||||
|
||||
private fun extractAssignExpr(type: IrType, locId: Label<DbLocation>, parent: Label<out DbExprparent>, idx: Int, callable: Label<out DbCallable>, enclosingStmt: Label<out DbStmt>) =
|
||||
tw.getFreshIdLabel<DbAssignexpr>().also {
|
||||
val typeResults = useType(type)
|
||||
@@ -3436,7 +3464,7 @@ open class KotlinFileExtractor(
|
||||
|
||||
tw.writeHasLocation(id, locId)
|
||||
tw.writeCallableBinding(id.cast<DbCaller>(), methodId)
|
||||
extractCallValueArguments(id, e, id, callable, 0)
|
||||
extractCallValueArguments(id, e, e.symbol.owner, locId, id, callable, 0)
|
||||
val dr = e.dispatchReceiver
|
||||
if (dr != null) {
|
||||
extractExpressionExpr(dr, callable, id, -1, id)
|
||||
@@ -3614,12 +3642,7 @@ open class KotlinFileExtractor(
|
||||
tw.writeNamestrings(v.toString(), v.toString(), id)
|
||||
}
|
||||
v == null -> {
|
||||
val id = tw.getFreshIdLabel<DbNullliteral>()
|
||||
val type = useType(e.type) // class;kotlin.Nothing
|
||||
val locId = tw.getLocation(e)
|
||||
tw.writeExprs_nullliteral(id, type.javaResult.id, exprParent.parent, exprParent.idx)
|
||||
tw.writeExprsKotlinType(id, type.kotlinResult.id)
|
||||
extractExprContext(id, locId, callable, exprParent.enclosingStmt)
|
||||
extractNull(e.type, tw.getLocation(e), exprParent.parent, exprParent.idx, callable, exprParent.enclosingStmt)
|
||||
}
|
||||
else -> {
|
||||
logger.errorElement("Unrecognised IrConst: " + v.javaClass, e)
|
||||
@@ -5516,5 +5539,6 @@ open class KotlinFileExtractor(
|
||||
JVMOVERLOADS_METHOD(9),
|
||||
DEFAULT_ARGUMENTS_METHOD(10),
|
||||
INTERFACE_FORWARDER(11),
|
||||
ENUM_CONSTRUCTOR_ARGUMENT(12),
|
||||
}
|
||||
}
|
||||
|
||||
9
java/ql/consistency-queries/callArgs.ql
Normal file
9
java/ql/consistency-queries/callArgs.ql
Normal file
@@ -0,0 +1,9 @@
|
||||
import java
|
||||
|
||||
from Call call, Callable c
|
||||
where
|
||||
count(call.getAnArgument()) != c.getNumberOfParameters() and
|
||||
call.getCallee() = c and
|
||||
not exists(Parameter p | c.getAParameter() = p and p.isVarargs()) and
|
||||
call.getFile().isKotlinSourceFile()
|
||||
select call, c, count(call.getAnArgument()), c.getNumberOfParameters()
|
||||
@@ -174,6 +174,8 @@ classes.kt:
|
||||
# 49| 0: [ClassInstanceExpr] new Enum(...)
|
||||
# 49| -3: [TypeAccess] Enum<Direction>
|
||||
# 49| 0: [TypeAccess] Direction
|
||||
# 49| 0: [NullLiteral] null
|
||||
# 49| 1: [IntegerLiteral] 0
|
||||
# 49| 1: [BlockStmt] { ... }
|
||||
# 50| 5: [FieldDeclaration] Direction NORTH;
|
||||
# 50| -1: [TypeAccess] Direction
|
||||
@@ -209,6 +211,8 @@ classes.kt:
|
||||
# 53| 0: [ClassInstanceExpr] new Enum(...)
|
||||
# 53| -3: [TypeAccess] Enum<Color>
|
||||
# 53| 0: [TypeAccess] Color
|
||||
# 53| 0: [NullLiteral] null
|
||||
# 53| 1: [IntegerLiteral] 0
|
||||
# 53| 1: [BlockStmt] { ... }
|
||||
# 53| 0: [ExprStmt] <Expr>;
|
||||
# 53| 0: [KtInitializerAssignExpr] ...=...
|
||||
|
||||
@@ -3358,6 +3358,8 @@ exprs.kt:
|
||||
# 174| 0: [ClassInstanceExpr] new Enum(...)
|
||||
# 174| -3: [TypeAccess] Enum<Direction>
|
||||
# 174| 0: [TypeAccess] Direction
|
||||
# 174| 0: [NullLiteral] null
|
||||
# 174| 1: [IntegerLiteral] 0
|
||||
# 174| 1: [BlockStmt] { ... }
|
||||
# 175| 5: [FieldDeclaration] Direction NORTH;
|
||||
# 175| -1: [TypeAccess] Direction
|
||||
@@ -3393,6 +3395,8 @@ exprs.kt:
|
||||
# 178| 0: [ClassInstanceExpr] new Enum(...)
|
||||
# 178| -3: [TypeAccess] Enum<Color>
|
||||
# 178| 0: [TypeAccess] Color
|
||||
# 178| 0: [NullLiteral] null
|
||||
# 178| 1: [IntegerLiteral] 0
|
||||
# 178| 1: [BlockStmt] { ... }
|
||||
# 178| 0: [ExprStmt] <Expr>;
|
||||
# 178| 0: [KtInitializerAssignExpr] ...=...
|
||||
|
||||
@@ -1470,9 +1470,11 @@
|
||||
| exprs.kt:170:9:170:17 | r2.height | exprs.kt:165:1:172:1 | foo | VarAccess |
|
||||
| exprs.kt:170:9:170:21 | ...=... | exprs.kt:165:1:172:1 | foo | AssignExpr |
|
||||
| exprs.kt:170:21:170:21 | 3 | exprs.kt:165:1:172:1 | foo | IntegerLiteral |
|
||||
| exprs.kt:174:1:176:1 | 0 | exprs.kt:174:6:176:1 | Direction | IntegerLiteral |
|
||||
| exprs.kt:174:1:176:1 | Direction | exprs.kt:174:6:176:1 | Direction | TypeAccess |
|
||||
| exprs.kt:174:1:176:1 | Enum<Direction> | exprs.kt:174:6:176:1 | Direction | TypeAccess |
|
||||
| exprs.kt:174:1:176:1 | new Enum(...) | exprs.kt:174:6:176:1 | Direction | ClassInstanceExpr |
|
||||
| exprs.kt:174:1:176:1 | null | exprs.kt:174:6:176:1 | Direction | NullLiteral |
|
||||
| exprs.kt:175:5:175:10 | ...=... | exprs.kt:0:0:0:0 | <clinit> | KtInitializerAssignExpr |
|
||||
| exprs.kt:175:5:175:10 | Direction | exprs.kt:0:0:0:0 | <clinit> | TypeAccess |
|
||||
| exprs.kt:175:5:175:10 | Direction | exprs.kt:0:0:0:0 | <clinit> | TypeAccess |
|
||||
@@ -1497,9 +1499,11 @@
|
||||
| exprs.kt:175:25:175:28 | Direction | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| exprs.kt:175:25:175:28 | Direction.EAST | exprs.kt:0:0:0:0 | <clinit> | VarAccess |
|
||||
| exprs.kt:175:25:175:28 | new Direction(...) | exprs.kt:0:0:0:0 | <clinit> | ClassInstanceExpr |
|
||||
| exprs.kt:178:1:182:1 | 0 | exprs.kt:178:6:182:1 | Color | IntegerLiteral |
|
||||
| exprs.kt:178:1:182:1 | Color | exprs.kt:178:6:182:1 | Color | TypeAccess |
|
||||
| exprs.kt:178:1:182:1 | Enum<Color> | exprs.kt:178:6:182:1 | Color | TypeAccess |
|
||||
| exprs.kt:178:1:182:1 | new Enum(...) | exprs.kt:178:6:182:1 | Color | ClassInstanceExpr |
|
||||
| exprs.kt:178:1:182:1 | null | exprs.kt:178:6:182:1 | Color | NullLiteral |
|
||||
| exprs.kt:178:18:178:29 | ...=... | exprs.kt:178:6:182:1 | Color | KtInitializerAssignExpr |
|
||||
| exprs.kt:178:18:178:29 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| exprs.kt:178:18:178:29 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
|
||||
@@ -88,6 +88,8 @@ A.kt:
|
||||
# 23| 0: [ClassInstanceExpr] new Enum(...)
|
||||
# 23| -3: [TypeAccess] Enum<Enu>
|
||||
# 23| 0: [TypeAccess] Enu
|
||||
# 23| 0: [NullLiteral] null
|
||||
# 23| 1: [IntegerLiteral] 0
|
||||
# 23| 1: [BlockStmt] { ... }
|
||||
# 24| 5: [FieldDeclaration] Enu A;
|
||||
# 24| -1: [TypeAccess] Enu
|
||||
|
||||
@@ -231,9 +231,11 @@
|
||||
| enumClass.kt:0:0:0:0 | EnumWithFunctions[] | TypeAccess |
|
||||
| enumClass.kt:0:0:0:0 | String | TypeAccess |
|
||||
| enumClass.kt:0:0:0:0 | String | TypeAccess |
|
||||
| enumClass.kt:1:1:4:1 | 0 | IntegerLiteral |
|
||||
| enumClass.kt:1:1:4:1 | Enum<EnumClass> | TypeAccess |
|
||||
| enumClass.kt:1:1:4:1 | EnumClass | TypeAccess |
|
||||
| enumClass.kt:1:1:4:1 | new Enum(...) | ClassInstanceExpr |
|
||||
| enumClass.kt:1:1:4:1 | null | NullLiteral |
|
||||
| enumClass.kt:1:22:1:31 | ...=... | KtInitializerAssignExpr |
|
||||
| enumClass.kt:1:22:1:31 | int | TypeAccess |
|
||||
| enumClass.kt:1:22:1:31 | int | TypeAccess |
|
||||
@@ -256,9 +258,11 @@
|
||||
| enumClass.kt:3:5:3:12 | EnumClass.enum2 | VarAccess |
|
||||
| enumClass.kt:3:5:3:12 | new EnumClass(...) | ClassInstanceExpr |
|
||||
| enumClass.kt:3:11:3:11 | 1 | IntegerLiteral |
|
||||
| enumClass.kt:6:1:16:1 | 0 | IntegerLiteral |
|
||||
| enumClass.kt:6:1:16:1 | Enum<EnumWithFunctions> | TypeAccess |
|
||||
| enumClass.kt:6:1:16:1 | EnumWithFunctions | TypeAccess |
|
||||
| enumClass.kt:6:1:16:1 | new Enum(...) | ClassInstanceExpr |
|
||||
| enumClass.kt:6:1:16:1 | null | NullLiteral |
|
||||
| enumClass.kt:8:3:11:4 | ...=... | KtInitializerAssignExpr |
|
||||
| enumClass.kt:8:3:11:4 | <implicit coercion to unit> | ImplicitCoercionToUnitExpr |
|
||||
| enumClass.kt:8:3:11:4 | EnumWithFunctions | TypeAccess |
|
||||
|
||||
Reference in New Issue
Block a user