KT-37861 'this' is uninitialized in constructor default parameters

This commit is contained in:
Dmitry Petrov
2020-03-30 14:12:09 +03:00
parent 078cf02c8a
commit cec64a2ec7
10 changed files with 102 additions and 0 deletions
@@ -1207,6 +1207,10 @@ public class FunctionCodegen {
@NotNull MemberCodegen<?> parentCodegen,
@NotNull Method defaultMethod
) {
if (methodContext instanceof ConstructorContext) {
((ConstructorContext) methodContext).setThisInitialized(false);
}
GenerationState state = parentCodegen.state;
JvmMethodSignature signature = state.getTypeMapper().mapSignatureWithGeneric(functionDescriptor, methodContext.getContextKind());
@@ -854,6 +854,19 @@ class CodegenAnnotatingVisitor extends KtVisitorVoid {
checkSamCall(call);
}
@Override
public void visitParameter(@NotNull KtParameter parameter) {
PsiElement parent = parameter.getParent(); // KtParameterList
if (parent != null && parent.getParent() instanceof KtConstructor<?>) {
KtExpression defaultValue = parameter.getDefaultValue();
if (defaultValue != null) {
withinUninitializedClass(defaultValue, () -> defaultValue.accept(this));
}
} else {
super.visitParameter(parameter);
}
}
private void withinUninitializedClass(@NotNull KtElement element, @NotNull Runnable operation) {
ClassDescriptor currentClass = peekFromStack(classStack);
assert currentClass != null : element.getClass().getSimpleName() + " should be inside a class: " + element.getText();
@@ -4349,6 +4349,16 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
runTest("compiler/testData/codegen/box/closures/captureInSuperConstructorCall/outerCapturedInObject2.kt");
}
@TestMetadata("outerCapturedInPrimaryConstructorDefaultParameter.kt")
public void testOuterCapturedInPrimaryConstructorDefaultParameter() throws Exception {
runTest("compiler/testData/codegen/box/closures/captureInSuperConstructorCall/outerCapturedInPrimaryConstructorDefaultParameter.kt");
}
@TestMetadata("outerCapturedInSecondaryConstructorDefaultParameter.kt")
public void testOuterCapturedInSecondaryConstructorDefaultParameter() throws Exception {
runTest("compiler/testData/codegen/box/closures/captureInSuperConstructorCall/outerCapturedInSecondaryConstructorDefaultParameter.kt");
}
@TestMetadata("outerEnumEntryCapturedInLambdaInInnerClass.kt")
public void testOuterEnumEntryCapturedInLambdaInInnerClass() throws Exception {
runTest("compiler/testData/codegen/box/closures/captureInSuperConstructorCall/outerEnumEntryCapturedInLambdaInInnerClass.kt");
@@ -0,0 +1,10 @@
// IGNORE_BACKEND: JS_IR
// IGNORE_BACKEND_FIR: JVM_IR
class Outer(val x: Any) {
inner class Inner(
val fn: () -> String = { x.toString() }
)
}
fun box() = Outer("OK").Inner().fn()
@@ -0,0 +1,15 @@
// IGNORE_BACKEND: JS_IR
// IGNORE_BACKEND_FIR: JVM_IR
class Outer(val x: Any) {
inner class Inner(
val fn: () -> String
) {
constructor(
unused: Int,
fn: () -> String = { x.toString() }
) : this(fn)
}
}
fun box() = Outer("OK").Inner(1).fn()
@@ -4369,6 +4369,16 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
runTest("compiler/testData/codegen/box/closures/captureInSuperConstructorCall/outerCapturedInObject2.kt");
}
@TestMetadata("outerCapturedInPrimaryConstructorDefaultParameter.kt")
public void testOuterCapturedInPrimaryConstructorDefaultParameter() throws Exception {
runTest("compiler/testData/codegen/box/closures/captureInSuperConstructorCall/outerCapturedInPrimaryConstructorDefaultParameter.kt");
}
@TestMetadata("outerCapturedInSecondaryConstructorDefaultParameter.kt")
public void testOuterCapturedInSecondaryConstructorDefaultParameter() throws Exception {
runTest("compiler/testData/codegen/box/closures/captureInSuperConstructorCall/outerCapturedInSecondaryConstructorDefaultParameter.kt");
}
@TestMetadata("outerEnumEntryCapturedInLambdaInInnerClass.kt")
public void testOuterEnumEntryCapturedInLambdaInInnerClass() throws Exception {
runTest("compiler/testData/codegen/box/closures/captureInSuperConstructorCall/outerEnumEntryCapturedInLambdaInInnerClass.kt");
@@ -4369,6 +4369,16 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
runTest("compiler/testData/codegen/box/closures/captureInSuperConstructorCall/outerCapturedInObject2.kt");
}
@TestMetadata("outerCapturedInPrimaryConstructorDefaultParameter.kt")
public void testOuterCapturedInPrimaryConstructorDefaultParameter() throws Exception {
runTest("compiler/testData/codegen/box/closures/captureInSuperConstructorCall/outerCapturedInPrimaryConstructorDefaultParameter.kt");
}
@TestMetadata("outerCapturedInSecondaryConstructorDefaultParameter.kt")
public void testOuterCapturedInSecondaryConstructorDefaultParameter() throws Exception {
runTest("compiler/testData/codegen/box/closures/captureInSuperConstructorCall/outerCapturedInSecondaryConstructorDefaultParameter.kt");
}
@TestMetadata("outerEnumEntryCapturedInLambdaInInnerClass.kt")
public void testOuterEnumEntryCapturedInLambdaInInnerClass() throws Exception {
runTest("compiler/testData/codegen/box/closures/captureInSuperConstructorCall/outerEnumEntryCapturedInLambdaInInnerClass.kt");
@@ -4349,6 +4349,16 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
runTest("compiler/testData/codegen/box/closures/captureInSuperConstructorCall/outerCapturedInObject2.kt");
}
@TestMetadata("outerCapturedInPrimaryConstructorDefaultParameter.kt")
public void testOuterCapturedInPrimaryConstructorDefaultParameter() throws Exception {
runTest("compiler/testData/codegen/box/closures/captureInSuperConstructorCall/outerCapturedInPrimaryConstructorDefaultParameter.kt");
}
@TestMetadata("outerCapturedInSecondaryConstructorDefaultParameter.kt")
public void testOuterCapturedInSecondaryConstructorDefaultParameter() throws Exception {
runTest("compiler/testData/codegen/box/closures/captureInSuperConstructorCall/outerCapturedInSecondaryConstructorDefaultParameter.kt");
}
@TestMetadata("outerEnumEntryCapturedInLambdaInInnerClass.kt")
public void testOuterEnumEntryCapturedInLambdaInInnerClass() throws Exception {
runTest("compiler/testData/codegen/box/closures/captureInSuperConstructorCall/outerEnumEntryCapturedInLambdaInInnerClass.kt");
@@ -3609,6 +3609,16 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
runTest("compiler/testData/codegen/box/closures/captureInSuperConstructorCall/outerCapturedInObject2.kt");
}
@TestMetadata("outerCapturedInPrimaryConstructorDefaultParameter.kt")
public void testOuterCapturedInPrimaryConstructorDefaultParameter() throws Exception {
runTest("compiler/testData/codegen/box/closures/captureInSuperConstructorCall/outerCapturedInPrimaryConstructorDefaultParameter.kt");
}
@TestMetadata("outerCapturedInSecondaryConstructorDefaultParameter.kt")
public void testOuterCapturedInSecondaryConstructorDefaultParameter() throws Exception {
runTest("compiler/testData/codegen/box/closures/captureInSuperConstructorCall/outerCapturedInSecondaryConstructorDefaultParameter.kt");
}
@TestMetadata("outerEnumEntryCapturedInLambdaInInnerClass.kt")
public void testOuterEnumEntryCapturedInLambdaInInnerClass() throws Exception {
runTest("compiler/testData/codegen/box/closures/captureInSuperConstructorCall/outerEnumEntryCapturedInLambdaInInnerClass.kt");
@@ -3609,6 +3609,16 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
runTest("compiler/testData/codegen/box/closures/captureInSuperConstructorCall/outerCapturedInObject2.kt");
}
@TestMetadata("outerCapturedInPrimaryConstructorDefaultParameter.kt")
public void testOuterCapturedInPrimaryConstructorDefaultParameter() throws Exception {
runTest("compiler/testData/codegen/box/closures/captureInSuperConstructorCall/outerCapturedInPrimaryConstructorDefaultParameter.kt");
}
@TestMetadata("outerCapturedInSecondaryConstructorDefaultParameter.kt")
public void testOuterCapturedInSecondaryConstructorDefaultParameter() throws Exception {
runTest("compiler/testData/codegen/box/closures/captureInSuperConstructorCall/outerCapturedInSecondaryConstructorDefaultParameter.kt");
}
@TestMetadata("outerEnumEntryCapturedInLambdaInInnerClass.kt")
public void testOuterEnumEntryCapturedInLambdaInInnerClass() throws Exception {
runTest("compiler/testData/codegen/box/closures/captureInSuperConstructorCall/outerEnumEntryCapturedInLambdaInInnerClass.kt");