Skip to content

Commit

Permalink
Clear DF info for variables assigned in 'try' #KT-17929 Fixed
Browse files Browse the repository at this point in the history
  • Loading branch information
mglukhikh committed May 26, 2017
1 parent 0fd70df commit adbece8
Show file tree
Hide file tree
Showing 10 changed files with 54 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
import org.jetbrains.kotlin.config.LanguageFeature;
import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.diagnostics.Errors;
import org.jetbrains.kotlin.psi.*;
Expand Down Expand Up @@ -513,11 +514,20 @@ public KotlinTypeInfo visitTryExpression(@NotNull KtTryExpression expression, Ex
}
}

KotlinTypeInfo result = TypeInfoFactoryKt.noTypeInfo(context);
KotlinTypeInfo tryResult = facade.getTypeInfo(tryBlock, context);
ExpressionTypingContext tryOutputContext = context.replaceExpectedType(NO_EXPECTED_TYPE);
if (!nothingInAllCatchBranches &&
facade.getComponents().languageVersionSettings.supportsFeature(LanguageFeature.SoundSmartCastsAfterTry)) {
PreliminaryLoopVisitor tryVisitor = PreliminaryLoopVisitor.visitTryBlock(expression);
tryOutputContext = tryOutputContext.replaceDataFlowInfo(
tryVisitor.clearDataFlowInfoForAssignedLocalVariables(tryOutputContext.dataFlowInfo,
components.languageVersionSettings)
);
}

KotlinTypeInfo result = TypeInfoFactoryKt.noTypeInfo(tryOutputContext);
if (finallyBlock != null) {
result = facade.getTypeInfo(finallyBlock.getFinalExpression(),
context.replaceExpectedType(NO_EXPECTED_TYPE));
result = facade.getTypeInfo(finallyBlock.getFinalExpression(), tryOutputContext);
}
else if (nothingInAllCatchBranches) {
result = tryResult;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package org.jetbrains.kotlin.types.expressions
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor
import org.jetbrains.kotlin.psi.KtLoopExpression
import org.jetbrains.kotlin.psi.KtTryExpression
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValue
import org.jetbrains.kotlin.resolve.calls.smartcasts.IdentifierInfo
Expand Down Expand Up @@ -59,5 +60,12 @@ class PreliminaryLoopVisitor private constructor() : AssignedVariablesSearcher()
loopExpression.accept(visitor, null)
return visitor
}

@JvmStatic
fun visitTryBlock(tryExpression: KtTryExpression): PreliminaryLoopVisitor {
val visitor = PreliminaryLoopVisitor()
tryExpression.tryBlock.accept(visitor, null)
return visitor
}
}
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// !LANGUAGE: +SoundSmartCastsAfterTry

fun bar(arg: Any?) = arg

fun foo() {
Expand All @@ -6,7 +8,7 @@ fun foo() {
try {
s = "Test"
} catch (ex: Exception) {}
bar(<!DEBUG_INFO_CONSTANT!>s<!>)
if (<!SENSELESS_COMPARISON!><!DEBUG_INFO_CONSTANT!>s<!> != null<!>) { }
<!DEBUG_INFO_CONSTANT!>s<!><!UNSAFE_CALL!>.<!>hashCode()
bar(s)
if (s != null) { }
s<!UNSAFE_CALL!>.<!>hashCode()
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
// !LANGUAGE: +SoundSmartCastsAfterTry

fun foo() {
var s: String?
s = "Test"
try {
s = null
} catch (ex: Exception) {}
<!DEBUG_INFO_SMARTCAST!>s<!>.hashCode()
s<!UNSAFE_CALL!>.<!>hashCode()
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// !LANGUAGE: +SoundSmartCastsAfterTry

fun bar() {}

fun foo() {
Expand All @@ -10,5 +12,5 @@ fun foo() {
finally {
bar()
}
<!DEBUG_INFO_SMARTCAST!>s<!>.hashCode()
s<!UNSAFE_CALL!>.<!>hashCode()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
fun foo() {
var s: String?
s = "Test"
try {
s = null
} catch (ex: Exception) {}
<!DEBUG_INFO_SMARTCAST!>s<!>.hashCode()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package

public fun foo(): kotlin.Unit
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
// !LANGUAGE: +SoundSmartCastsAfterTry

fun foo() {
var s: String?
s = "Test"
try {
s = "Other"
} catch (ex: Exception) {}
<!DEBUG_INFO_SMARTCAST!>s<!>.hashCode()
// Problem: here we do not see that 's' is always not-null
s<!UNSAFE_CALL!>.<!>hashCode()
}
Original file line number Diff line number Diff line change
Expand Up @@ -21186,6 +21186,12 @@ public void testSetNullInTryFinally() throws Exception {
doTest(fileName);
}

@TestMetadata("setNullInTryUnsound.kt")
public void testSetNullInTryUnsound() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/smartCasts/varnotnull/setNullInTryUnsound.kt");
doTest(fileName);
}

@TestMetadata("setSameInTry.kt")
public void testSetSameInTry() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/smartCasts/varnotnull/setSameInTry.kt");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ enum class LanguageFeature(

ArrayLiteralsInAnnotations(KOTLIN_1_2),
InlineDefaultFunctionalParameters(KOTLIN_1_2),
SoundSmartCastsAfterTry(KOTLIN_1_2),

// Experimental features

Expand Down

0 comments on commit adbece8

Please sign in to comment.