diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java index 73c04def32f..3c11651d2bd 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java @@ -4022,10 +4022,14 @@ public class ExpressionCodegen extends KtVisitor impleme return StackValue.operation(base.type, base.kotlinType, v -> { base.put(base.type, base.kotlinType, v); v.dup(); - Label ok = new Label(); - v.ifnonnull(ok); - v.invokestatic(IntrinsicMethods.INTRINSICS_CLASS_NAME, "throwNpe", "()V", false); - v.mark(ok); + if (state.getLanguageVersionSettings().getApiVersion().compareTo(ApiVersion.KOTLIN_1_4) >= 0) { + v.invokestatic(IntrinsicMethods.INTRINSICS_CLASS_NAME, "checkNotNull", "(Ljava/lang/Object;)V", false); + } else { + Label ok = new Label(); + v.ifnonnull(ok); + v.invokestatic(IntrinsicMethods.INTRINSICS_CLASS_NAME, "throwNpe", "()V", false); + v.mark(ok); + } return null; }); } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/nullCheck/RedundantNullCheckMethodTransformer.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/nullCheck/RedundantNullCheckMethodTransformer.kt index 5ecfe358952..e169dba2e7a 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/nullCheck/RedundantNullCheckMethodTransformer.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/nullCheck/RedundantNullCheckMethodTransformer.kt @@ -38,6 +38,7 @@ import org.jetbrains.org.objectweb.asm.tree.* class RedundantNullCheckMethodTransformer(private val generationState: GenerationState) : MethodTransformer() { override fun transform(internalClassName: String, methodNode: MethodNode) { + @Suppress("ControlFlowWithEmptyBody") while (TransformerPass(internalClassName, methodNode, generationState).run()) { } } @@ -69,6 +70,7 @@ class RedundantNullCheckMethodTransformer(private val generationState: Generatio val value = when { insn.isInstanceOfOrNullCheck() -> frame.top() + insn.isCheckNotNull() -> frame.top() insn.isCheckExpressionValueIsNotNull() -> frame.peek(1) else -> null } as? StrictBasicValue ?: continue @@ -84,6 +86,7 @@ class RedundantNullCheckMethodTransformer(private val generationState: Generatio opcode == Opcodes.IFNULL || opcode == Opcodes.IFNONNULL || opcode == Opcodes.INSTANCEOF || + isCheckNotNull() || isCheckExpressionValueIsNotNull() private fun transformTrivialChecks(nullabilityMap: Map) { @@ -95,6 +98,9 @@ class RedundantNullCheckMethodTransformer(private val generationState: Generatio Opcodes.INSTANCEOF -> transformInstanceOf(insn as TypeInsnNode, nullability, value) Opcodes.INVOKESTATIC -> { + if (insn.isCheckNotNull()) { + transformTrivialCheckNotNull(insn, nullability) + } if (insn.isCheckExpressionValueIsNotNull()) { transformTrivialCheckExpressionValueIsNotNull(insn, nullability) } @@ -134,6 +140,15 @@ class RedundantNullCheckMethodTransformer(private val generationState: Generatio } } + private fun transformTrivialCheckNotNull(insn: AbstractInsnNode, nullability: Nullability) { + if (nullability != Nullability.NOT_NULL) return + val dupInsn = insn.previous?.takeIf { it.opcode == Opcodes.DUP } ?: return + methodNode.instructions.run { + remove(dupInsn) + remove(insn) + } + } + private fun transformTrivialCheckExpressionValueIsNotNull(insn: AbstractInsnNode, nullability: Nullability) { if (nullability != Nullability.NOT_NULL) return val ldcInsn = insn.previous?.takeIf { it.opcode == Opcodes.LDC } ?: return @@ -168,6 +183,14 @@ class RedundantNullCheckMethodTransformer(private val generationState: Generatio } } + insn.isCheckNotNull() -> { + val dupInsn = insn.previous ?: continue@insnLoop + if (dupInsn.opcode != Opcodes.DUP) continue@insnLoop + val aLoadInsn = dupInsn.previous ?: continue@insnLoop + if (aLoadInsn.opcode != Opcodes.ALOAD) continue@insnLoop + addDependentCheck(insn, aLoadInsn as VarInsnNode) + } + insn.isCheckParameterIsNotNull() -> { val ldcInsn = insn.previous ?: continue@insnLoop if (ldcInsn.opcode != Opcodes.LDC) continue@insnLoop @@ -198,7 +221,7 @@ class RedundantNullCheckMethodTransformer(private val generationState: Generatio private fun addDependentCheck(insn: AbstractInsnNode, aLoadInsn: VarInsnNode) { checksDependingOnVariable.getOrPut(aLoadInsn.`var`) { - SmartList() + SmartList() }.add(insn) } @@ -224,8 +247,7 @@ class RedundantNullCheckMethodTransformer(private val generationState: Generatio injectAssumptionsForNullCheck(varIndex, insn as JumpInsnNode) Opcodes.INVOKESTATIC -> { when { - insn.isCheckParameterIsNotNull() || - insn.isCheckExpressionValueIsNotNull() -> + insn.isCheckNotNull() || insn.isCheckParameterIsNotNull() || insn.isCheckExpressionValueIsNotNull() -> injectAssumptionsForNotNullAssertion(varIndex, insn) insn.isPseudo(PseudoInsn.STORE_NOT_NULL) -> injectCodeForStoreNotNull(insn) @@ -276,6 +298,11 @@ class RedundantNullCheckMethodTransformer(private val generationState: Generatio } private fun NullabilityAssumptions.injectAssumptionsForNotNullAssertion(varIndex: Int, insn: AbstractInsnNode) { + // ALOAD v + // DUP + // INVOKESTATIC checkNotNull + // <...> -- v is not null here (otherwise an exception was thrown) + // ALOAD v // LDC * // INVOKESTATIC checkParameterIsNotNull @@ -396,6 +423,13 @@ internal fun AbstractInsnNode.isInstanceOfOrNullCheck() = opcode == Opcodes.IFNULL || opcode == Opcodes.IFNONNULL +internal fun AbstractInsnNode.isCheckNotNull() = + isInsn(Opcodes.INVOKESTATIC) { + owner == IntrinsicMethods.INTRINSICS_CLASS_NAME && + name == "checkNotNull" && + desc == "(Ljava/lang/Object;)V" + } + internal fun AbstractInsnNode.isCheckParameterIsNotNull() = isInsn(Opcodes.INVOKESTATIC) { owner == IntrinsicMethods.INTRINSICS_CLASS_NAME && diff --git a/compiler/testData/codegen/box/nullCheckOptimization/exclExclThrowsNpe_1_4.kt b/compiler/testData/codegen/box/nullCheckOptimization/exclExclThrowsNpe_1_4.kt new file mode 100644 index 00000000000..b66c5368a9c --- /dev/null +++ b/compiler/testData/codegen/box/nullCheckOptimization/exclExclThrowsNpe_1_4.kt @@ -0,0 +1,14 @@ +// !API_VERSION: LATEST +// TARGET_BACKEND: JVM +// IGNORE_BACKEND: JVM_IR + +fun box(): String { + val s: String? = null + try { + s!! + return "Fail: NPE should have been thrown" + } catch (e: Throwable) { + if (e::class != NullPointerException::class) return "Fail: exception class should be NPE: ${e::class}" + return "OK" + } +} diff --git a/compiler/testData/codegen/bytecodeText/deadCodeElimination/arrayConstructor.kt b/compiler/testData/codegen/bytecodeText/deadCodeElimination/arrayConstructor.kt index d171aa9c575..6d1685ec981 100644 --- a/compiler/testData/codegen/bytecodeText/deadCodeElimination/arrayConstructor.kt +++ b/compiler/testData/codegen/bytecodeText/deadCodeElimination/arrayConstructor.kt @@ -6,3 +6,4 @@ fun box() { // 0 IFNONNULL // 0 ATHROW // 0 throwNpe +// 0 checkNotNull diff --git a/compiler/testData/codegen/bytecodeText/deadCodeElimination/boxing.kt b/compiler/testData/codegen/bytecodeText/deadCodeElimination/boxing.kt index b1b5240cad7..c969b2bead9 100644 --- a/compiler/testData/codegen/bytecodeText/deadCodeElimination/boxing.kt +++ b/compiler/testData/codegen/bytecodeText/deadCodeElimination/boxing.kt @@ -20,3 +20,4 @@ fun box() { // 1 IFNONNULL // 1 throwNpe // 0 ATHROW +// 0 checkNotNull diff --git a/compiler/testData/codegen/bytecodeText/deadCodeElimination/boxingNotOptimizable.kt b/compiler/testData/codegen/bytecodeText/deadCodeElimination/boxingNotOptimizable.kt index 66471397a4f..aa68d3445b7 100644 --- a/compiler/testData/codegen/bytecodeText/deadCodeElimination/boxingNotOptimizable.kt +++ b/compiler/testData/codegen/bytecodeText/deadCodeElimination/boxingNotOptimizable.kt @@ -19,3 +19,4 @@ fun box(u: Int) { // 1 IFNONNULL // 1 throwNpe // 0 ATHROW +// 0 checkNotNull diff --git a/compiler/testData/codegen/bytecodeText/deadCodeElimination/literal.kt b/compiler/testData/codegen/bytecodeText/deadCodeElimination/literal.kt index a3e1485370b..db277ebe35d 100644 --- a/compiler/testData/codegen/bytecodeText/deadCodeElimination/literal.kt +++ b/compiler/testData/codegen/bytecodeText/deadCodeElimination/literal.kt @@ -10,3 +10,4 @@ fun box() { // 0 IFNONNULL // 0 throwNpe // 0 ATHROW +// 0 checkNotNull diff --git a/compiler/testData/codegen/bytecodeText/deadCodeElimination/simpleConstructor.kt b/compiler/testData/codegen/bytecodeText/deadCodeElimination/simpleConstructor.kt index dfec1f31eba..56e223136b5 100644 --- a/compiler/testData/codegen/bytecodeText/deadCodeElimination/simpleConstructor.kt +++ b/compiler/testData/codegen/bytecodeText/deadCodeElimination/simpleConstructor.kt @@ -13,3 +13,4 @@ fun box() { // 0 IFNONNULL // 0 throwNpe // 0 ATHROW +// 0 checkNotNull diff --git a/compiler/testData/codegen/bytecodeText/deadCodeElimination/simpleConstructorNotRedundant.kt b/compiler/testData/codegen/bytecodeText/deadCodeElimination/simpleConstructorNotRedundant.kt index f160e4c4969..426fc06db86 100644 --- a/compiler/testData/codegen/bytecodeText/deadCodeElimination/simpleConstructorNotRedundant.kt +++ b/compiler/testData/codegen/bytecodeText/deadCodeElimination/simpleConstructorNotRedundant.kt @@ -17,3 +17,4 @@ fun box() { // 1 IFNONNULL // 1 throwNpe // 0 ATHROW +// 0 checkNotNull diff --git a/compiler/testData/codegen/bytecodeText/deadCodeElimination/simpleConstructorNotRedundantNotOptimizable.kt b/compiler/testData/codegen/bytecodeText/deadCodeElimination/simpleConstructorNotRedundantNotOptimizable.kt index 1c929f8220c..cd2c75cc163 100644 --- a/compiler/testData/codegen/bytecodeText/deadCodeElimination/simpleConstructorNotRedundantNotOptimizable.kt +++ b/compiler/testData/codegen/bytecodeText/deadCodeElimination/simpleConstructorNotRedundantNotOptimizable.kt @@ -16,3 +16,4 @@ fun box(u: Int) { // 1 IFNONNULL // 1 throwNpe // 0 ATHROW +// 0 checkNotNull diff --git a/compiler/testData/codegen/bytecodeText/inline/inlineReturnsNothing1.kt b/compiler/testData/codegen/bytecodeText/inline/inlineReturnsNothing1.kt index 74e36070427..6917d999aea 100644 --- a/compiler/testData/codegen/bytecodeText/inline/inlineReturnsNothing1.kt +++ b/compiler/testData/codegen/bytecodeText/inline/inlineReturnsNothing1.kt @@ -1,4 +1,4 @@ -// NB '!!' uses Intrinsics.throwNpe() +// NB '!!' uses Intrinsics.throwNpe/checkNotNull inline fun exit(): Nothing = null!! fun box(): String { @@ -13,4 +13,4 @@ fun box(): String { return a } -// 1 ATHROW \ No newline at end of file +// 1 ATHROW diff --git a/compiler/testData/codegen/bytecodeText/nullCheckOptimization/multipleExclExcl_1_4.kt b/compiler/testData/codegen/bytecodeText/nullCheckOptimization/multipleExclExcl_1_4.kt new file mode 100644 index 00000000000..88cdf076176 --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/nullCheckOptimization/multipleExclExcl_1_4.kt @@ -0,0 +1,13 @@ +// !API_VERSION: LATEST +// IGNORE_BACKEND: JVM_IR + +fun test(s: String?): Int { + s!! + s!! + s!! + s!! + s!! + return 0 +} + +// 1 checkNotNull diff --git a/compiler/testData/codegen/bytecodeText/nullCheckOptimization/nullCheckAfterExclExcl_1_4.kt b/compiler/testData/codegen/bytecodeText/nullCheckOptimization/nullCheckAfterExclExcl_1_4.kt new file mode 100644 index 00000000000..276a372e2d5 --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/nullCheckOptimization/nullCheckAfterExclExcl_1_4.kt @@ -0,0 +1,14 @@ +// !API_VERSION: LATEST +// IGNORE_BACKEND: JVM_IR + +fun test(s: String?): Int { + s!! + if (s == null) { + return 5 + } + return 3 +} + +// 1 checkNotNull +// 0 IFNULL +// 0 IFNONNULL diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index 8c6df6b83a6..a0f68d4e142 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -16404,6 +16404,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/nullCheckOptimization"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true); } + @TestMetadata("exclExclThrowsNpe_1_4.kt") + public void testExclExclThrowsNpe_1_4() throws Exception { + runTest("compiler/testData/codegen/box/nullCheckOptimization/exclExclThrowsNpe_1_4.kt"); + } + @TestMetadata("isNullable.kt") public void testIsNullable() throws Exception { runTest("compiler/testData/codegen/box/nullCheckOptimization/isNullable.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java index dcbaa65f0e4..a82c9e29936 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java @@ -3266,11 +3266,21 @@ public class BytecodeTextTestGenerated extends AbstractBytecodeTextTest { runTest("compiler/testData/codegen/bytecodeText/nullCheckOptimization/kt12839.kt"); } + @TestMetadata("multipleExclExcl_1_4.kt") + public void testMultipleExclExcl_1_4() throws Exception { + runTest("compiler/testData/codegen/bytecodeText/nullCheckOptimization/multipleExclExcl_1_4.kt"); + } + @TestMetadata("notNullAsNotNullable.kt") public void testNotNullAsNotNullable() throws Exception { runTest("compiler/testData/codegen/bytecodeText/nullCheckOptimization/notNullAsNotNullable.kt"); } + @TestMetadata("nullCheckAfterExclExcl_1_4.kt") + public void testNullCheckAfterExclExcl_1_4() throws Exception { + runTest("compiler/testData/codegen/bytecodeText/nullCheckOptimization/nullCheckAfterExclExcl_1_4.kt"); + } + @TestMetadata("primitiveCheck.kt") public void testPrimitiveCheck() throws Exception { runTest("compiler/testData/codegen/bytecodeText/nullCheckOptimization/primitiveCheck.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index abd0748aec1..e380850bf6d 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -16404,6 +16404,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/nullCheckOptimization"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true); } + @TestMetadata("exclExclThrowsNpe_1_4.kt") + public void testExclExclThrowsNpe_1_4() throws Exception { + runTest("compiler/testData/codegen/box/nullCheckOptimization/exclExclThrowsNpe_1_4.kt"); + } + @TestMetadata("isNullable.kt") public void testIsNullable() throws Exception { runTest("compiler/testData/codegen/box/nullCheckOptimization/isNullable.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java index 654be2e60cb..f8ddc5cb5ec 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java @@ -15289,6 +15289,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/nullCheckOptimization"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM_IR, true); } + @TestMetadata("exclExclThrowsNpe_1_4.kt") + public void testExclExclThrowsNpe_1_4() throws Exception { + runTest("compiler/testData/codegen/box/nullCheckOptimization/exclExclThrowsNpe_1_4.kt"); + } + @TestMetadata("isNullable.kt") public void testIsNullable() throws Exception { runTest("compiler/testData/codegen/box/nullCheckOptimization/isNullable.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBytecodeTextTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBytecodeTextTestGenerated.java index a0c364fdca8..24252c08781 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBytecodeTextTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBytecodeTextTestGenerated.java @@ -3236,11 +3236,21 @@ public class IrBytecodeTextTestGenerated extends AbstractIrBytecodeTextTest { runTest("compiler/testData/codegen/bytecodeText/nullCheckOptimization/kt12839.kt"); } + @TestMetadata("multipleExclExcl_1_4.kt") + public void testMultipleExclExcl_1_4() throws Exception { + runTest("compiler/testData/codegen/bytecodeText/nullCheckOptimization/multipleExclExcl_1_4.kt"); + } + @TestMetadata("notNullAsNotNullable.kt") public void testNotNullAsNotNullable() throws Exception { runTest("compiler/testData/codegen/bytecodeText/nullCheckOptimization/notNullAsNotNullable.kt"); } + @TestMetadata("nullCheckAfterExclExcl_1_4.kt") + public void testNullCheckAfterExclExcl_1_4() throws Exception { + runTest("compiler/testData/codegen/bytecodeText/nullCheckOptimization/nullCheckAfterExclExcl_1_4.kt"); + } + @TestMetadata("primitiveCheck.kt") public void testPrimitiveCheck() throws Exception { runTest("compiler/testData/codegen/bytecodeText/nullCheckOptimization/primitiveCheck.kt"); diff --git a/compiler/util/src/org/jetbrains/kotlin/config/ApiVersion.kt b/compiler/util/src/org/jetbrains/kotlin/config/ApiVersion.kt index 7c7dcd9f8df..6ebede19b11 100644 --- a/compiler/util/src/org/jetbrains/kotlin/config/ApiVersion.kt +++ b/compiler/util/src/org/jetbrains/kotlin/config/ApiVersion.kt @@ -52,6 +52,9 @@ class ApiVersion private constructor( @JvmField val KOTLIN_1_3 = createByLanguageVersion(LanguageVersion.KOTLIN_1_3) + @JvmField + val KOTLIN_1_4 = createByLanguageVersion(LanguageVersion.KOTLIN_1_4) + @JvmField val LATEST: ApiVersion = createByLanguageVersion(LanguageVersion.values().last()) diff --git a/libraries/stdlib/jvm/runtime/kotlin/jvm/internal/Intrinsics.java b/libraries/stdlib/jvm/runtime/kotlin/jvm/internal/Intrinsics.java index fb7f5f4a114..84432b4d7f4 100644 --- a/libraries/stdlib/jvm/runtime/kotlin/jvm/internal/Intrinsics.java +++ b/libraries/stdlib/jvm/runtime/kotlin/jvm/internal/Intrinsics.java @@ -10,9 +10,8 @@ import kotlin.SinceKotlin; import kotlin.UninitializedPropertyAccessException; import java.util.Arrays; -import java.util.List; -@SuppressWarnings("unused") +@SuppressWarnings({"unused", "WeakerAccess"}) public class Intrinsics { private Intrinsics() { } @@ -23,13 +22,13 @@ public class Intrinsics { public static void checkNotNull(Object object) { if (object == null) { - throwNpe(); + throwJavaNpe(); } } public static void checkNotNull(Object object, String message) { if (object == null) { - throwNpe(message); + throwJavaNpe(message); } } @@ -41,6 +40,16 @@ public class Intrinsics { throw sanitizeStackTrace(new KotlinNullPointerException(message)); } + @SinceKotlin(version = "1.4") + public static void throwJavaNpe() { + throw sanitizeStackTrace(new NullPointerException()); + } + + @SinceKotlin(version = "1.4") + public static void throwJavaNpe(String message) { + throw sanitizeStackTrace(new NullPointerException(message)); + } + public static void throwUninitializedProperty(String message) { throw sanitizeStackTrace(new UninitializedPropertyAccessException(message)); } diff --git a/libraries/tools/binary-compatibility-validator/reference-public-api/kotlin-stdlib-runtime-merged.txt b/libraries/tools/binary-compatibility-validator/reference-public-api/kotlin-stdlib-runtime-merged.txt index d210107d59e..ccb39354064 100644 --- a/libraries/tools/binary-compatibility-validator/reference-public-api/kotlin-stdlib-runtime-merged.txt +++ b/libraries/tools/binary-compatibility-validator/reference-public-api/kotlin-stdlib-runtime-merged.txt @@ -3451,6 +3451,8 @@ public class kotlin/jvm/internal/Intrinsics { public static fun throwIllegalArgument (Ljava/lang/String;)V public static fun throwIllegalState ()V public static fun throwIllegalState (Ljava/lang/String;)V + public static fun throwJavaNpe ()V + public static fun throwJavaNpe (Ljava/lang/String;)V public static fun throwNpe ()V public static fun throwNpe (Ljava/lang/String;)V public static fun throwUndefinedForReified ()V