Proper instructions for elvis operator

We should not mark elvis operator unused, for the rhs may have desired side-effects
This commit is contained in:
Andrey Breslav
2013-12-05 12:51:18 +04:00
parent 3629a539e4
commit 4ca90e9c68
8 changed files with 50 additions and 2 deletions
@@ -101,6 +101,7 @@ public interface JetControlFlowBuilder {
enum PredefinedOperation {
AND,
OR,
ELVIS,
NOT_NULL_ASSERTION
}
void predefinedOperation(@NotNull JetExpression expression, @Nullable PredefinedOperation operation);
@@ -250,7 +250,7 @@ public class JetControlFlowProcessor {
public void visitBinaryExpression(@NotNull JetBinaryExpression expression) {
JetSimpleNameExpression operationReference = expression.getOperationReference();
IElementType operationType = operationReference.getReferencedNameElementType();
if (!ImmutableSet.of(ANDAND, OROR, EQ, ELVIS).contains(operationType)) {
if (!ImmutableSet.of(ANDAND, OROR, EQ, JetTokens.ELVIS).contains(operationType)) {
mark(expression);
}
JetExpression right = expression.getRight();
@@ -296,13 +296,14 @@ public class JetControlFlowProcessor {
generateBothArguments(expression);
}
}
else if (operationType == ELVIS) {
else if (operationType == JetTokens.ELVIS) {
generateInstructions(expression.getLeft(), false);
Label afterElvis = builder.createUnboundLabel();
builder.jumpOnTrue(afterElvis);
if (right != null) {
generateInstructions(right, false);
}
builder.predefinedOperation(expression, JetControlFlowBuilder.PredefinedOperation.ELVIS);
builder.bindLabel(afterElvis);
}
else if (operationType == JetTokens.EQEQ || operationType == JetTokens.EXCLEQ) {
@@ -9,6 +9,7 @@ L0:
ret L1 NEXT:[<END>]
- jt(L2) NEXT:[r(null), <END>] PREV:[]
- r(null) PREV:[]
- r(return ?: null) PREV:[]
L1:
L2:
<END> NEXT:[<SINK>] PREV:[ret L1]
@@ -0,0 +1,23 @@
== test ==
fun test(a: Any?) {
a ?: ""
}
---------------------
L0:
<START>
v(a: Any?)
w(a)
mark({ a ?: "" })
r(a)
jt(L2) NEXT:[mark(""), <END>]
mark("")
r("")
r(a ?: "")
L1:
L2:
<END> NEXT:[<SINK>] PREV:[jt(L2), r(a ?: "")]
error:
<ERROR> PREV:[]
sink:
<SINK> PREV:[<ERROR>, <END>]
=====================
+3
View File
@@ -0,0 +1,3 @@
fun test(a: Any?) {
a ?: ""
}
@@ -0,0 +1,9 @@
fun foo(a: Any?) {
a ?: ""
}
fun foo1(a: Any?) {
a ?: sideEffect()
}
fun sideEffect() {}
@@ -142,6 +142,11 @@ public class ControlFlowTestGenerated extends AbstractControlFlowTest {
doTest("compiler/testData/cfg/invoke.kt");
}
@TestMetadata("lastElvis.kt")
public void testLastElvis() throws Exception {
doTest("compiler/testData/cfg/lastElvis.kt");
}
@TestMetadata("LazyBooleans.kt")
public void testLazyBooleans() throws Exception {
doTest("compiler/testData/cfg/LazyBooleans.kt");
@@ -1572,6 +1572,11 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage
doTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/unreachableCode.kt");
}
@TestMetadata("unusedElvis.kt")
public void testUnusedElvis() throws Exception {
doTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/unusedElvis.kt");
}
}
@TestMetadata("compiler/testData/diagnostics/tests/controlStructures")