mirror of
https://github.com/github/codeql.git
synced 2025-12-24 12:46:34 +01:00
Tolerate nullable references to anonymous classes
This also adds a test case illustrating when this can arise
This commit is contained in:
committed by
Ian Lynagh
parent
8d6ae50d21
commit
c0f3988aaa
@@ -363,19 +363,14 @@ open class KotlinUsesExtractor(
|
||||
classLabelResult.shortName)
|
||||
}
|
||||
|
||||
fun useAnonymousClass(c: IrClass): TypeResults {
|
||||
var res = tw.lm.anonymousTypeMapping[c]
|
||||
if (res == null) {
|
||||
val javaResult = TypeResult(tw.getFreshIdLabel<DbClass>(), "", "")
|
||||
val kotlinResult = TypeResult(tw.getFreshIdLabel<DbKt_notnull_type>(), "", "")
|
||||
tw.writeKt_notnull_types(kotlinResult.id, javaResult.id)
|
||||
res = TypeResults(javaResult, kotlinResult)
|
||||
tw.lm.anonymousTypeMapping[c] = res
|
||||
fun useAnonymousClass(c: IrClass) =
|
||||
tw.lm.anonymousTypeMapping.getOrPut(c) {
|
||||
TypeResults(
|
||||
TypeResult(tw.getFreshIdLabel<DbClass>(), "", ""),
|
||||
TypeResult(fakeKotlinType(), "TODO", "TODO")
|
||||
)
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
fun fakeKotlinType(): Label<out DbKt_type> {
|
||||
val fakeKotlinPackageId: Label<DbPackage> = tw.getLabelFor("@\"FakeKotlinPackage\"", {
|
||||
tw.writePackages(it, "fake.kotlin")
|
||||
@@ -396,9 +391,6 @@ open class KotlinUsesExtractor(
|
||||
if (args?.isNotEmpty() == true) {
|
||||
logger.error("Anonymous class with unexpected type arguments")
|
||||
}
|
||||
if (hasQuestionMark) {
|
||||
logger.error("Unexpected nullable anonymous class")
|
||||
}
|
||||
|
||||
return useAnonymousClass(c)
|
||||
}
|
||||
|
||||
@@ -528,6 +528,56 @@ local_anonymous.kt:
|
||||
# 26| 0: [TypeAccess] Unit
|
||||
# 26| 1: [ClassInstanceExpr] new LocalClass(...)
|
||||
# 26| -3: [TypeAccess] LocalClass
|
||||
# 29| 7: [Method] nullableAnonymous
|
||||
# 29| 5: [BlockStmt] { ... }
|
||||
# 35| 0: [ReturnStmt] return ...
|
||||
# 29| 0: [StmtExpr] <Stmt>
|
||||
# 29| 0: [BlockStmt] { ... }
|
||||
# 29| 0: [LocalTypeDeclStmt] class ...
|
||||
# 29| 0: [AnonymousClass,LocalClass] new Object(...) { ... }
|
||||
# 29| 1: [Constructor]
|
||||
# 29| 5: [BlockStmt] { ... }
|
||||
# 29| 0: [SuperConstructorInvocationStmt] super(...)
|
||||
# 29| 1: [BlockStmt] { ... }
|
||||
# 30| 0: [ExprStmt] <Expr>;
|
||||
# 30| 0: [KtInitializerAssignExpr] ...=...
|
||||
# 30| 0: [VarAccess] x
|
||||
# 30| 2: [Method] getX
|
||||
# 30| 5: [BlockStmt] { ... }
|
||||
# 30| 0: [ReturnStmt] return ...
|
||||
# 30| 0: [VarAccess] this.x
|
||||
# 30| -1: [ThisAccess] this
|
||||
# 30| 2: [Method] setX
|
||||
#-----| 4: (Parameters)
|
||||
# 30| 0: [Parameter] <set-?>
|
||||
# 30| 5: [BlockStmt] { ... }
|
||||
# 30| 0: [ExprStmt] <Expr>;
|
||||
# 30| 0: [AssignExpr] ...=...
|
||||
# 30| 0: [VarAccess] this.x
|
||||
# 30| -1: [ThisAccess] this
|
||||
# 30| 1: [VarAccess] <set-?>
|
||||
# 30| 2: [FieldDeclaration] int x;
|
||||
# 30| -1: [TypeAccess] int
|
||||
# 30| 0: [IntegerLiteral] 1
|
||||
# 32| 5: [Method] member
|
||||
# 32| 5: [BlockStmt] { ... }
|
||||
# 33| 0: [LocalVariableDeclStmt] var ...;
|
||||
# 33| 1: [LocalVariableDeclExpr] maybeThis
|
||||
# 33| 0: [WhenExpr] when ...
|
||||
# 33| 0: [WhenBranch] ... -> ...
|
||||
# 33| 0: [ValueEQExpr] ... (value equals) ...
|
||||
# 33| 0: [MethodAccess] getX(...)
|
||||
# 33| -1: [ThisAccess] this
|
||||
# 33| 1: [IntegerLiteral] 1
|
||||
# 33| 1: [ExprStmt] <Expr>;
|
||||
# 33| 0: [ThisAccess] this
|
||||
# 33| 1: [WhenBranch] ... -> ...
|
||||
# 33| 0: [BooleanLiteral] true
|
||||
# 33| 1: [ExprStmt] <Expr>;
|
||||
# 33| 0: [NullLiteral] null
|
||||
# 29| 1: [ExprStmt] <Expr>;
|
||||
# 29| 0: [ClassInstanceExpr] new (...)
|
||||
# 29| -3: [TypeAccess] Object
|
||||
superChain.kt:
|
||||
# 0| [CompilationUnit] superChain
|
||||
# 1| 1: [Class,GenericType,ParameterizedType] SuperChain1
|
||||
|
||||
@@ -7,3 +7,4 @@
|
||||
| classes.kt:89:16:89:44 | new Interface3<Integer>(...) { ... } | classes.kt:89:16:89:44 | new (...) | | classes.kt:89:16:89:44 | Interface3<Integer> | classes.kt:89:16:89:44 | class ... |
|
||||
| classes.kt:127:16:134:9 | new Object(...) { ... } | classes.kt:127:16:134:9 | new (...) | | classes.kt:127:16:134:9 | Object | classes.kt:127:16:134:9 | class ... |
|
||||
| local_anonymous.kt:5:16:7:9 | new Object(...) { ... } | local_anonymous.kt:5:16:7:9 | new (...) | | local_anonymous.kt:5:16:7:9 | Object | local_anonymous.kt:5:16:7:9 | class ... |
|
||||
| local_anonymous.kt:29:31:35:5 | new Object(...) { ... } | local_anonymous.kt:29:31:35:5 | new (...) | | local_anonymous.kt:29:31:35:5 | Object | local_anonymous.kt:29:31:35:5 | class ... |
|
||||
|
||||
@@ -34,13 +34,14 @@
|
||||
| classes.kt:119:13:121:13 | Local2 | C1$Local2 | final, private |
|
||||
| classes.kt:127:16:134:9 | new Object(...) { ... } | <anonymous class> | final, private |
|
||||
| classes.kt:129:17:131:17 | Local3 | C1$$Local3 | final, private |
|
||||
| local_anonymous.kt:3:1:28:1 | Class1 | LocalAnonymous.Class1 | final, public |
|
||||
| local_anonymous.kt:3:1:36:1 | Class1 | LocalAnonymous.Class1 | final, public |
|
||||
| local_anonymous.kt:5:16:7:9 | new Object(...) { ... } | <anonymous class> | final, private |
|
||||
| local_anonymous.kt:11:9:11:24 | | Class1$ | final, private |
|
||||
| local_anonymous.kt:16:23:16:49 | new Function2<Integer,Integer,Integer>(...) { ... } | <anonymous class> | final, private |
|
||||
| local_anonymous.kt:17:23:17:49 | new Function2<Integer,Integer,Integer>(...) { ... } | <anonymous class> | final, private |
|
||||
| local_anonymous.kt:21:21:21:31 | new Function1<Class1,Unit>(...) { ... } | <anonymous class> | final, private |
|
||||
| local_anonymous.kt:25:9:25:27 | LocalClass | LocalAnonymous.Class1$LocalClass | final, private |
|
||||
| local_anonymous.kt:29:31:35:5 | new Object(...) { ... } | <anonymous class> | final, private |
|
||||
| superChain.kt:1:1:1:33 | SuperChain1 | SuperChain1 | public |
|
||||
| superChain.kt:2:1:2:60 | SuperChain2 | SuperChain2 | public |
|
||||
| superChain.kt:3:1:3:60 | SuperChain3 | SuperChain3 | public |
|
||||
|
||||
@@ -34,13 +34,14 @@ superCall
|
||||
| classes.kt:119:13:121:13 | super(...) |
|
||||
| classes.kt:127:16:134:9 | super(...) |
|
||||
| classes.kt:129:17:131:17 | super(...) |
|
||||
| local_anonymous.kt:3:1:28:1 | super(...) |
|
||||
| local_anonymous.kt:3:1:36:1 | super(...) |
|
||||
| local_anonymous.kt:5:16:7:9 | super(...) |
|
||||
| local_anonymous.kt:11:9:11:24 | super(...) |
|
||||
| local_anonymous.kt:16:23:16:49 | super(...) |
|
||||
| local_anonymous.kt:17:23:17:49 | super(...) |
|
||||
| local_anonymous.kt:21:21:21:31 | super(...) |
|
||||
| local_anonymous.kt:25:9:25:27 | super(...) |
|
||||
| local_anonymous.kt:29:31:35:5 | super(...) |
|
||||
| superChain.kt:1:1:1:33 | super(...) |
|
||||
| superChain.kt:2:33:2:57 | super(...) |
|
||||
| superChain.kt:3:33:3:57 | super(...) |
|
||||
|
||||
@@ -2,5 +2,5 @@
|
||||
| classes.kt:118:9:123:9 | class ... | classes.kt:118:9:123:9 | | classes.kt:117:5:124:5 | fn2 | classes.kt:109:1:136:1 | C1 |
|
||||
| classes.kt:119:13:121:13 | class ... | classes.kt:119:13:121:13 | Local2 | classes.kt:118:9:123:9 | localFn | classes.kt:109:1:136:1 | C1 |
|
||||
| classes.kt:129:17:131:17 | class ... | classes.kt:129:17:131:17 | Local3 | classes.kt:128:13:133:13 | fn | classes.kt:127:16:134:9 | new Object(...) { ... } |
|
||||
| local_anonymous.kt:11:9:11:24 | class ... | local_anonymous.kt:11:9:11:24 | | local_anonymous.kt:10:5:13:5 | fn2 | local_anonymous.kt:3:1:28:1 | Class1 |
|
||||
| local_anonymous.kt:25:9:25:27 | class ... | local_anonymous.kt:25:9:25:27 | LocalClass | local_anonymous.kt:24:5:27:5 | fn5 | local_anonymous.kt:3:1:28:1 | Class1 |
|
||||
| local_anonymous.kt:11:9:11:24 | class ... | local_anonymous.kt:11:9:11:24 | | local_anonymous.kt:10:5:13:5 | fn2 | local_anonymous.kt:3:1:36:1 | Class1 |
|
||||
| local_anonymous.kt:25:9:25:27 | class ... | local_anonymous.kt:25:9:25:27 | LocalClass | local_anonymous.kt:24:5:27:5 | fn5 | local_anonymous.kt:3:1:36:1 | Class1 |
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
anonymousObjects
|
||||
| local_anonymous.kt:5:16:7:9 | new (...) | local_anonymous.kt:5:16:7:9 | new Object(...) { ... } | anonymous | local |
|
||||
| local_anonymous.kt:29:31:35:5 | new (...) | local_anonymous.kt:29:31:35:5 | new Object(...) { ... } | anonymous | local |
|
||||
localFunctions
|
||||
| local_anonymous.kt:11:9:11:24 | fnLocal | local_anonymous.kt:11:9:11:24 | | not anonymous | local |
|
||||
lambdas
|
||||
|
||||
@@ -25,4 +25,12 @@ class Class1 {
|
||||
class LocalClass {}
|
||||
LocalClass()
|
||||
}
|
||||
|
||||
fun nullableAnonymous() = object {
|
||||
var x = 1
|
||||
|
||||
fun member() {
|
||||
val maybeThis = if (x == 1) this else null // Expression with nullable anonymous type
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
| classes.kt:127:16:134:9 | new Object(...) { ... } | file://<external>/Object.class:0:0:0:0 | Object |
|
||||
| classes.kt:129:17:131:17 | Local3 | file://<external>/Object.class:0:0:0:0 | Object |
|
||||
| classes.kt:129:17:131:17 | Local3<Integer> | file://<external>/Object.class:0:0:0:0 | Object |
|
||||
| local_anonymous.kt:3:1:28:1 | Class1 | file://<external>/Object.class:0:0:0:0 | Object |
|
||||
| local_anonymous.kt:3:1:36:1 | Class1 | file://<external>/Object.class:0:0:0:0 | Object |
|
||||
| local_anonymous.kt:5:16:7:9 | new Object(...) { ... } | file://<external>/Object.class:0:0:0:0 | Object |
|
||||
| local_anonymous.kt:11:9:11:24 | | file://<external>/Object.class:0:0:0:0 | Object |
|
||||
| local_anonymous.kt:16:23:16:49 | new Function2<Integer,Integer,Integer>(...) { ... } | file://<external>/Function2.class:0:0:0:0 | Function2<Integer,Integer,Integer> |
|
||||
@@ -52,6 +52,7 @@
|
||||
| local_anonymous.kt:21:21:21:31 | new Function1<Class1,Unit>(...) { ... } | file://<external>/Function1.class:0:0:0:0 | Function1<Class1,Unit> |
|
||||
| local_anonymous.kt:21:21:21:31 | new Function1<Class1,Unit>(...) { ... } | file://<external>/FunctionReference.class:0:0:0:0 | FunctionReference |
|
||||
| local_anonymous.kt:25:9:25:27 | LocalClass | file://<external>/Object.class:0:0:0:0 | Object |
|
||||
| local_anonymous.kt:29:31:35:5 | new Object(...) { ... } | file://<external>/Object.class:0:0:0:0 | Object |
|
||||
| superChain.kt:1:1:1:33 | SuperChain1 | file://<external>/Object.class:0:0:0:0 | Object |
|
||||
| superChain.kt:1:1:1:33 | SuperChain1<T3,String> | file://<external>/Object.class:0:0:0:0 | Object |
|
||||
| superChain.kt:1:1:1:33 | SuperChain1<T5,String> | file://<external>/Object.class:0:0:0:0 | Object |
|
||||
|
||||
Reference in New Issue
Block a user