improved processing of local declarations in cfg construction

This commit is contained in:
svtk
2011-11-07 18:49:30 +04:00
parent d1787a5f6e
commit c71d9796a2
11 changed files with 662 additions and 162 deletions
@@ -93,7 +93,10 @@ public class JetControlFlowGraphTraverser<D> {
Collection<D> incomingEdgesData = Sets.newHashSet();
for (Instruction previousInstruction : allPreviousInstructions) {
incomingEdgesData.add(dataMap.get(previousInstruction).getSecond());
Pair<D, D> previousData = dataMap.get(previousInstruction);
if (previousData != null) {
incomingEdgesData.add(previousData.getSecond());
}
}
Pair<D, D> mergedData = instructionsMergeStrategy.execute(instruction, incomingEdgesData);
if (!mergedData.equals(previousDataValue)) {
@@ -22,6 +22,7 @@ import static org.jetbrains.jet.lang.diagnostics.Errors.*;
/**
* @author abreslav
* @author svtk
*/
public class JetControlFlowProcessor {
@@ -547,7 +548,10 @@ public class JetControlFlowProcessor {
public void visitNamedFunction(JetNamedFunction function) {
JetExpression bodyExpression = function.getBodyExpression();
if (bodyExpression != null) {
Label afterFunctionLabel = builder.createUnboundLabel();
builder.nondeterministicJump(afterFunctionLabel);
generate(function, bodyExpression);
builder.bindLabel(afterFunctionLabel);
}
}
@@ -557,7 +561,10 @@ public class JetControlFlowProcessor {
JetBlockExpression bodyExpression = functionLiteral.getBodyExpression();
if (bodyExpression != null) {
List<JetElement> statements = bodyExpression.getStatements();
Label afterFunctionLiteralLabel = builder.createUnboundLabel();
builder.nondeterministicJump(afterFunctionLiteralLabel);
generateSubroutineControlFlow(functionLiteral, statements);
builder.bindLabel(afterFunctionLiteralLabel);
}
builder.read(expression);
}
@@ -744,28 +751,9 @@ public class JetControlFlowProcessor {
functions.add(localDeclaration);
}
}
Queue<Label> declarationLabels = new LinkedList<Label>();
for (JetDeclaration function : functions) {
declarationLabels.add(builder.createUnboundLabel());
value(function, inCondition);
}
builder.nondeterministicJump(Lists.newArrayList(declarationLabels));
for (JetDeclaration function : functions) {
if (function instanceof JetNamedDeclaration) {
if (function instanceof JetDeclarationWithBody) {
JetExpression bodyExpression = ((JetDeclarationWithBody) function).getBodyExpression();
generate(function, bodyExpression != null ? bodyExpression : function);
}
else {
generate(function, function);
}
}
else {
generate(declaration, function);
}
builder.bindLabel(declarationLabels.remove());
}
builder.read(expression);
}
@@ -92,11 +92,20 @@ public class JetFlowInformationProvider {
@Override
public void visitUnconditionalJump(UnconditionalJumpInstruction instruction) {
redirectToPrevInstructions(instruction);
}
private void redirectToPrevInstructions(Instruction instruction) {
for (Instruction previousInstruction : instruction.getPreviousInstructions()) {
previousInstruction.accept(this);
}
}
@Override
public void visitNondeterministicJump(NondeterministicJumpInstruction instruction) {
redirectToPrevInstructions(instruction);
}
@Override
public void visitInstruction(Instruction instruction) {
if (instruction instanceof JetElementInstruction) {
@@ -127,7 +136,7 @@ public class JetFlowInformationProvider {
final Pseudocode pseudocode = pseudocodeMap.get(subroutine);
assert pseudocode != null;
JetControlFlowGraphTraverser<Map<VariableDescriptor, InitializationPoints>> traverser = JetControlFlowGraphTraverser.create(pseudocode, true);
JetControlFlowGraphTraverser<Map<VariableDescriptor, InitializationPoints>> traverser = JetControlFlowGraphTraverser.create(pseudocode, false);
JetControlFlowGraphTraverser.InstructionsMergeStrategy<Map<VariableDescriptor, InitializationPoints>> instructionsMergeStrategy =
new JetControlFlowGraphTraverser.InstructionsMergeStrategy<Map<VariableDescriptor, InitializationPoints>>() {
@@ -218,7 +227,7 @@ public class JetFlowInformationProvider {
JetProperty property = psiElement instanceof JetProperty ? (JetProperty) psiElement : null;
trace.report(Errors.VAL_REASSIGNMENT.on(expression, variableDescriptor, property == null ? new JetProperty[0] : new JetProperty[] { property }));
}
if (expression instanceof JetSimpleNameExpression && !analyzeLocalDeclaration && inAnonymousInitializers &&
if (expression instanceof JetSimpleNameExpression && inAnonymousInitializers &&
variableDescriptor instanceof PropertyDescriptor && !enterInitializationPoints.isInitialized() && exitInitializationPoints.isInitialized()) {
JetSimpleNameExpression simpleNameExpression = (JetSimpleNameExpression) expression;
if (simpleNameExpression.getReferencedNameElementType() != JetTokens.FIELD_IDENTIFIER) {
@@ -238,6 +247,14 @@ public class JetFlowInformationProvider {
trace.record(BindingContext.IS_INITIALIZED, (PropertyDescriptor) variable, initializationPoints.isInitialized());
}
}
for (Instruction instruction : pseudocode.getInstructions()) {
if (instruction instanceof LocalDeclarationInstruction) {
JetElement element = ((LocalDeclarationInstruction) instruction).getElement();
if (element instanceof JetNamedFunction) {
markUninitializedVariables(element, false, analyzeLocalDeclaration);
}
}
}
}
private Map<VariableDescriptor, InitializationPoints> prepareInitialMapForStartInstruction(Collection<VariableDescriptor> usedVariables, Collection<VariableDescriptor> declaredVariables) {
@@ -178,8 +178,7 @@ public class Pseudocode {
@Override
public void visitLocalDeclarationInstruction(LocalDeclarationInstruction instruction) {
instruction.getBody().postProcess();
instruction.setSink(getSinkInstruction());
super.visitLocalDeclarationInstruction(instruction);
instruction.setNext(getSinkInstruction());
}
@Override
@@ -224,29 +223,12 @@ public class Pseudocode {
@NotNull
private Instruction getJumpTarget(@NotNull Label targetLabel) {
return ((PseudocodeLabel)targetLabel).resolveToInstruction();
//return getTargetInstruction(((PseudocodeLabel) targetLabel).resolve());
}
// @NotNull
// private Instruction getTargetInstruction(@NotNull List<Instruction> instructions) {
// while (true) {
// assert instructions != null;
// Instruction targetInstruction = instructions.get(0);
//
// //if (false == targetInstruction instanceof UnconditionalJumpInstruction) {
// return targetInstruction;
// //}
//
//// Label label = ((UnconditionalJumpInstruction) targetInstruction).getTargetLabel();
//// instructions = ((PseudocodeLabel)label).resolve();
// }
// }
@NotNull
private Instruction getNextPosition(int currentPosition) {
int targetPosition = currentPosition + 1;
assert targetPosition < instructions.size() : currentPosition;
return instructions.get(targetPosition);
//return getTargetInstruction(instructions.subList(targetPosition, instructions.size()));
}
}
+18 -16
View File
@@ -1,10 +1,10 @@
== anonymous_0 ==
{1}
---------------------
l2:
l3:
<START> NEXT:[r(1)] PREV:[]
r(1) NEXT:[<END>] PREV:[<START>]
l3:
l4:
<END> NEXT:[<SINK>] PREV:[r(1)]
error:
<ERROR> NEXT:[] PREV:[]
@@ -42,9 +42,11 @@ l0:
r(foo) NEXT:[r(foo(a, 3))] PREV:[r(3)]
r(foo(a, 3)) NEXT:[r(genfun)] PREV:[r(foo)]
r(genfun) NEXT:[r(genfun<Any>())] PREV:[r(foo(a, 3))]
r(genfun<Any>()) NEXT:[df({1})] PREV:[r(genfun)]
df({1}) NEXT:[<SINK>, r({1})] PREV:[r(genfun<Any>())]
r({1}) NEXT:[r(flfun)] PREV:[df({1})]
r(genfun<Any>()) NEXT:[jmp?(l2)] PREV:[r(genfun)]
jmp?(l2) NEXT:[r({1}), df({1})] PREV:[r(genfun<Any>())]
df({1}) NEXT:[<SINK>] PREV:[jmp?(l2)]
l2:
r({1}) NEXT:[r(flfun)] PREV:[jmp?(l2)]
r(flfun) NEXT:[r(flfun {1})] PREV:[r({1})]
r(flfun {1}) NEXT:[r(3)] PREV:[r(flfun)]
r(3) NEXT:[r(4)] PREV:[r(flfun {1})]
@@ -60,26 +62,26 @@ l0:
r(2) NEXT:[r(+)] PREV:[r(1)]
r(+) NEXT:[r(1 + 2)] PREV:[r(2)]
r(1 + 2) NEXT:[r(a)] PREV:[r(+)]
r(a) NEXT:[jf(l4)] PREV:[r(1 + 2)]
jf(l4) NEXT:[r(a && true), r(true)] PREV:[r(a)]
r(true) NEXT:[r(a && true)] PREV:[jf(l4)]
l4:
r(a && true) NEXT:[r(a)] PREV:[jf(l4), r(true)]
r(a) NEXT:[jt(l5)] PREV:[r(a && true)]
jt(l5) NEXT:[r(false), r(a || false)] PREV:[r(a)]
r(false) NEXT:[r(a || false)] PREV:[jt(l5)]
r(a) NEXT:[jf(l5)] PREV:[r(1 + 2)]
jf(l5) NEXT:[r(a && true), r(true)] PREV:[r(a)]
r(true) NEXT:[r(a && true)] PREV:[jf(l5)]
l5:
r(a || false) NEXT:[<END>] PREV:[jt(l5), r(false)]
r(a && true) NEXT:[r(a)] PREV:[jf(l5), r(true)]
r(a) NEXT:[jt(l6)] PREV:[r(a && true)]
jt(l6) NEXT:[r(false), r(a || false)] PREV:[r(a)]
r(false) NEXT:[r(a || false)] PREV:[jt(l6)]
l6:
r(a || false) NEXT:[<END>] PREV:[jt(l6), r(false)]
l1:
<END> NEXT:[<SINK>] PREV:[r(a || false)]
error:
<ERROR> NEXT:[] PREV:[]
sink:
<SINK> NEXT:[] PREV:[df({1}), <END>]
l2:
l3:
<START> NEXT:[r(1)] PREV:[]
r(1) NEXT:[<END>] PREV:[<START>]
l3:
l4:
<END> NEXT:[<SINK>] PREV:[r(1)]
error:
<ERROR> NEXT:[] PREV:[]
+87 -83
View File
@@ -1,5 +1,5 @@
== t3 ==
fun t3() {
== t1 ==
fun t1() {
try {
1
} finally {
@@ -20,8 +20,8 @@ error:
sink:
<SINK> NEXT:[] PREV:[<END>]
=====================
== t3 ==
fun t3() {
== t2 ==
fun t2() {
try {
1
if (2 > 3) {
@@ -63,20 +63,20 @@ sink:
}
}
---------------------
l3:
l4:
<START> NEXT:[r(2)] PREV:[]
r(2) NEXT:[r(3)] PREV:[<START>]
r(3) NEXT:[r(>)] PREV:[r(2)]
r(>) NEXT:[r(2 > 3)] PREV:[r(3)]
r(2 > 3) NEXT:[jf(l5)] PREV:[r(>)]
jf(l5) NEXT:[read (Unit), ret l4] PREV:[r(2 > 3)]
ret l4 NEXT:[<END>] PREV:[jf(l5)]
* jmp(l6) NEXT:[<END>] PREV:[]
l5:
read (Unit) NEXT:[<END>] PREV:[jf(l5)]
l4:
r(2 > 3) NEXT:[jf(l6)] PREV:[r(>)]
jf(l6) NEXT:[read (Unit), ret l5] PREV:[r(2 > 3)]
ret l5 NEXT:[<END>] PREV:[jf(l6)]
* jmp(l7) NEXT:[<END>] PREV:[]
l6:
<END> NEXT:[<SINK>] PREV:[ret l4, read (Unit)]
read (Unit) NEXT:[<END>] PREV:[jf(l6)]
l5:
l7:
<END> NEXT:[<SINK>] PREV:[ret l5, read (Unit)]
error:
<ERROR> NEXT:[] PREV:[]
sink:
@@ -97,41 +97,43 @@ fun t3() {
}
---------------------
l0:
<START> NEXT:[jmp?(l2)] PREV:[]
jmp?(l2) NEXT:[r(2), r(1)] PREV:[<START>]
r(1) NEXT:[df({ () => if (2 > 3) { retu..)] PREV:[jmp?(l2)]
<START> NEXT:[jmp?(l2)] PREV:[]
jmp?(l2) NEXT:[r(2), r(1)] PREV:[<START>]
r(1) NEXT:[jmp?(l3)] PREV:[jmp?(l2)]
jmp?(l3) NEXT:[r({ () => if (2 > 3) { retur..), df({ () => if (2 > 3) { retu..)] PREV:[r(1)]
df({ () =>
if (2 > 3) {
return@
}
}) NEXT:[<SINK>, r({ () => if (2 > 3) { retur..)] PREV:[r(1)]
}) NEXT:[<SINK>] PREV:[jmp?(l3)]
l3:
r({ () =>
if (2 > 3) {
return@
}
}) NEXT:[r(2)] PREV:[df({ () => if (2 > 3) { retu..)]
}) NEXT:[r(2)] PREV:[jmp?(l3)]
l2:
r(2) NEXT:[<END>] PREV:[jmp?(l2), r({ () => if (2 > 3) { retur..)]
r(2) NEXT:[<END>] PREV:[jmp?(l2), r({ () => if (2 > 3) { retur..)]
l1:
<END> NEXT:[<SINK>] PREV:[r(2)]
<END> NEXT:[<SINK>] PREV:[r(2)]
error:
<ERROR> NEXT:[] PREV:[]
<ERROR> NEXT:[] PREV:[]
sink:
<SINK> NEXT:[] PREV:[df({ () => if (2 > 3) { retu..), <END>]
l3:
<SINK> NEXT:[] PREV:[df({ () => if (2 > 3) { retu..), <END>]
l4:
<START> NEXT:[r(2)] PREV:[]
r(2) NEXT:[r(3)] PREV:[<START>]
r(3) NEXT:[r(>)] PREV:[r(2)]
r(>) NEXT:[r(2 > 3)] PREV:[r(3)]
r(2 > 3) NEXT:[jf(l5)] PREV:[r(>)]
jf(l5) NEXT:[read (Unit), ret l4] PREV:[r(2 > 3)]
ret l4 NEXT:[<END>] PREV:[jf(l5)]
* jmp(l6) NEXT:[<END>] PREV:[]
l5:
read (Unit) NEXT:[<END>] PREV:[jf(l5)]
l4:
r(2 > 3) NEXT:[jf(l6)] PREV:[r(>)]
jf(l6) NEXT:[read (Unit), ret l5] PREV:[r(2 > 3)]
ret l5 NEXT:[<END>] PREV:[jf(l6)]
* jmp(l7) NEXT:[<END>] PREV:[]
l6:
<END> NEXT:[<SINK>] PREV:[ret l4, read (Unit)]
read (Unit) NEXT:[<END>] PREV:[jf(l6)]
l5:
l7:
<END> NEXT:[<SINK>] PREV:[ret l5, read (Unit)]
error:
<ERROR> NEXT:[] PREV:[]
sink:
@@ -149,32 +151,32 @@ sink:
}
}
---------------------
l2:
<START> NEXT:[jmp?(l4)] PREV:[]
jmp?(l4) NEXT:[r(2), r(1)] PREV:[<START>]
r(1) NEXT:[r(2)] PREV:[jmp?(l4)]
l3:
<START> NEXT:[jmp?(l5)] PREV:[]
jmp?(l5) NEXT:[r(2), r(1)] PREV:[<START>]
r(1) NEXT:[r(2)] PREV:[jmp?(l5)]
r(2) NEXT:[r(3)] PREV:[r(1)]
r(3) NEXT:[r(>)] PREV:[r(2)]
r(>) NEXT:[r(2 > 3)] PREV:[r(3)]
r(2 > 3) NEXT:[jf(l5)] PREV:[r(>)]
jf(l5) NEXT:[read (Unit), r(2)] PREV:[r(2 > 3)]
r(2) NEXT:[ret l3] PREV:[jf(l5)]
ret l3 NEXT:[<END>] PREV:[r(2)]
* jmp(l6) NEXT:[r(2)] PREV:[]
l5:
read (Unit) NEXT:[r(2)] PREV:[jf(l5)]
l4:
r(2 > 3) NEXT:[jf(l6)] PREV:[r(>)]
jf(l6) NEXT:[read (Unit), r(2)] PREV:[r(2 > 3)]
r(2) NEXT:[ret l4] PREV:[jf(l6)]
ret l4 NEXT:[<END>] PREV:[r(2)]
* jmp(l7) NEXT:[r(2)] PREV:[]
l6:
r(2) NEXT:[<END>] PREV:[jmp?(l4), read (Unit)]
l3:
<END> NEXT:[<SINK>] PREV:[ret l3, r(2)]
read (Unit) NEXT:[r(2)] PREV:[jf(l6)]
l5:
l7:
r(2) NEXT:[<END>] PREV:[jmp?(l5), read (Unit)]
l4:
<END> NEXT:[<SINK>] PREV:[ret l4, r(2)]
error:
<ERROR> NEXT:[] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<END>]
=====================
== t3 ==
fun t3() {
== t4 ==
fun t4() {
@{ () =>
try {
1
@@ -188,7 +190,8 @@ fun t3() {
}
---------------------
l0:
<START> NEXT:[df({ () => try { 1 if (2 > 3..)] PREV:[]
<START> NEXT:[jmp?(l2)] PREV:[]
jmp?(l2) NEXT:[r({ () => try { 1 if (2 > 3)..), df({ () => try { 1 if (2 > 3..)] PREV:[<START>]
df({ () =>
try {
1
@@ -198,7 +201,8 @@ l0:
} finally {
2
}
}) NEXT:[<SINK>, r({ () => try { 1 if (2 > 3)..)] PREV:[<START>]
}) NEXT:[<SINK>] PREV:[jmp?(l2)]
l2:
r({ () =>
try {
1
@@ -208,39 +212,39 @@ l0:
} finally {
2
}
}) NEXT:[<END>] PREV:[df({ () => try { 1 if (2 > 3..)]
}) NEXT:[<END>] PREV:[jmp?(l2)]
l1:
<END> NEXT:[<SINK>] PREV:[r({ () => try { 1 if (2 > 3)..)]
<END> NEXT:[<SINK>] PREV:[r({ () => try { 1 if (2 > 3)..)]
error:
<ERROR> NEXT:[] PREV:[]
<ERROR> NEXT:[] PREV:[]
sink:
<SINK> NEXT:[] PREV:[df({ () => try { 1 if (2 > 3..), <END>]
l2:
<START> NEXT:[jmp?(l4)] PREV:[]
jmp?(l4) NEXT:[r(2), r(1)] PREV:[<START>]
r(1) NEXT:[r(2)] PREV:[jmp?(l4)]
<SINK> NEXT:[] PREV:[df({ () => try { 1 if (2 > 3..), <END>]
l3:
<START> NEXT:[jmp?(l5)] PREV:[]
jmp?(l5) NEXT:[r(2), r(1)] PREV:[<START>]
r(1) NEXT:[r(2)] PREV:[jmp?(l5)]
r(2) NEXT:[r(3)] PREV:[r(1)]
r(3) NEXT:[r(>)] PREV:[r(2)]
r(>) NEXT:[r(2 > 3)] PREV:[r(3)]
r(2 > 3) NEXT:[jf(l5)] PREV:[r(>)]
jf(l5) NEXT:[read (Unit), r(2)] PREV:[r(2 > 3)]
r(2) NEXT:[ret l3] PREV:[jf(l5)]
ret l3 NEXT:[<END>] PREV:[r(2)]
* jmp(l6) NEXT:[r(2)] PREV:[]
l5:
read (Unit) NEXT:[r(2)] PREV:[jf(l5)]
l4:
r(2 > 3) NEXT:[jf(l6)] PREV:[r(>)]
jf(l6) NEXT:[read (Unit), r(2)] PREV:[r(2 > 3)]
r(2) NEXT:[ret l4] PREV:[jf(l6)]
ret l4 NEXT:[<END>] PREV:[r(2)]
* jmp(l7) NEXT:[r(2)] PREV:[]
l6:
r(2) NEXT:[<END>] PREV:[jmp?(l4), read (Unit)]
l3:
<END> NEXT:[<SINK>] PREV:[ret l3, r(2)]
read (Unit) NEXT:[r(2)] PREV:[jf(l6)]
l5:
l7:
r(2) NEXT:[<END>] PREV:[jmp?(l5), read (Unit)]
l4:
<END> NEXT:[<SINK>] PREV:[ret l4, r(2)]
error:
<ERROR> NEXT:[] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<END>]
=====================
== t3 ==
fun t3() {
== t5 ==
fun t5() {
@ while(true) {
try {
1
@@ -285,8 +289,8 @@ error:
sink:
<SINK> NEXT:[] PREV:[<END>]
=====================
== t3 ==
fun t3() {
== t6 ==
fun t6() {
try {
@ while(true) {
1
@@ -332,8 +336,8 @@ error:
sink:
<SINK> NEXT:[] PREV:[<END>]
=====================
== t3 ==
fun t3() {
== t7 ==
fun t7() {
try {
@ while(true) {
1
@@ -377,8 +381,8 @@ error:
sink:
<SINK> NEXT:[] PREV:[<END>]
=====================
== t3 ==
fun t3(a : Int) {
== t8 ==
fun t8(a : Int) {
@ for (i in 1..a) {
try {
1
@@ -427,8 +431,8 @@ error:
sink:
<SINK> NEXT:[] PREV:[<END>]
=====================
== t3 ==
fun t3(a : Int) {
== t9 ==
fun t9(a : Int) {
try {
@ for (i in 1..a) {
1
@@ -478,8 +482,8 @@ error:
sink:
<SINK> NEXT:[] PREV:[<END>]
=====================
== t3 ==
fun t3(a : Int) {
== t10 ==
fun t10(a : Int) {
try {
@ for (i in 1..a) {
1
@@ -527,8 +531,8 @@ error:
sink:
<SINK> NEXT:[] PREV:[<END>]
=====================
== tf ==
fun tf() {
== t11 ==
fun t11() {
try {
return 1
}
+10 -10
View File
@@ -1,4 +1,4 @@
fun t3() {
fun t1() {
try {
1
} finally {
@@ -6,7 +6,7 @@ fun t3() {
}
}
fun t3() {
fun t2() {
try {
1
if (2 > 3) {
@@ -30,7 +30,7 @@ fun t3() {
}
}
fun t3() {
fun t4() {
@{ () =>
try {
1
@@ -43,7 +43,7 @@ fun t3() {
}
}
fun t3() {
fun t5() {
@ while(true) {
try {
1
@@ -56,7 +56,7 @@ fun t3() {
}
}
fun t3() {
fun t6() {
try {
@ while(true) {
1
@@ -70,7 +70,7 @@ fun t3() {
}
}
fun t3() {
fun t7() {
try {
@ while(true) {
1
@@ -83,7 +83,7 @@ fun t3() {
}
}
fun t3(a : Int) {
fun t8(a : Int) {
@ for (i in 1..a) {
try {
1
@@ -96,7 +96,7 @@ fun t3(a : Int) {
}
}
fun t3(a : Int) {
fun t9(a : Int) {
try {
@ for (i in 1..a) {
1
@@ -110,7 +110,7 @@ fun t3(a : Int) {
}
}
fun t3(a : Int) {
fun t10(a : Int) {
try {
@ for (i in 1..a) {
1
@@ -123,7 +123,7 @@ fun t3(a : Int) {
}
}
fun tf() {
fun t11() {
try {
return 1
}
@@ -0,0 +1,402 @@
== C ==
class C() {
val a: Int = 1
class object {
val x : Int
{
$x = 1
}
fun foo() {
val b : Int = 1
doSmth(b)
}
}
}
---------------------
l0:
<START> NEXT:[r(1)] PREV:[]
r(1) NEXT:[w(a)] PREV:[<START>]
w(a) NEXT:[<END>] PREV:[r(1)]
l1:
<END> NEXT:[<SINK>] PREV:[w(a)]
error:
<ERROR> NEXT:[] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<END>]
=====================
== null ==
object {
val x : Int
{
$x = 1
}
fun foo() {
val b : Int = 1
doSmth(b)
}
}
---------------------
l0:
<START> NEXT:[r(1)] PREV:[]
r(1) NEXT:[w($x)] PREV:[<START>]
w($x) NEXT:[<END>] PREV:[r(1)]
l1:
<END> NEXT:[<SINK>] PREV:[w($x)]
error:
<ERROR> NEXT:[] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<END>]
=====================
== O ==
object O {
val x : Int
{
$x = 1
}
}
---------------------
l0:
<START> NEXT:[r(1)] PREV:[]
r(1) NEXT:[w($x)] PREV:[<START>]
w($x) NEXT:[<END>] PREV:[r(1)]
l1:
<END> NEXT:[<SINK>] PREV:[w($x)]
error:
<ERROR> NEXT:[] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<END>]
=====================
== doSmth ==
fun doSmth(i: Int) {}
---------------------
l0:
<START> NEXT:[read (Unit)] PREV:[]
read (Unit) NEXT:[<END>] PREV:[<START>]
l1:
<END> NEXT:[<SINK>] PREV:[read (Unit)]
error:
<ERROR> NEXT:[] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<END>]
=====================
== test1 ==
fun test1() {
val a = object {
val x : Int
{
$x = 1
}
}
}
---------------------
l0:
<START> NEXT:[r(1)] PREV:[]
r(1) NEXT:[w($x)] PREV:[<START>]
w($x) NEXT:[r(object { val x : Int { $x ..)] PREV:[r(1)]
r(object {
val x : Int
{
$x = 1
}
}) NEXT:[w(a)] PREV:[w($x)]
w(a) NEXT:[<END>] PREV:[r(object { val x : Int { $x ..)]
l1:
<END> NEXT:[<SINK>] PREV:[w(a)]
error:
<ERROR> NEXT:[] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<END>]
=====================
== test2 ==
fun test2() {
val b = 1
val a = object {
val x = b
}
}
---------------------
l0:
<START> NEXT:[r(1)] PREV:[]
r(1) NEXT:[w(b)] PREV:[<START>]
w(b) NEXT:[r(b)] PREV:[r(1)]
r(b) NEXT:[w(x)] PREV:[w(b)]
w(x) NEXT:[r(object { val x = b }) ] PREV:[r(b)]
r(object {
val x = b
}) NEXT:[w(a)] PREV:[w(x)]
w(a) NEXT:[<END>] PREV:[r(object { val x = b }) ]
l1:
<END> NEXT:[<SINK>] PREV:[w(a)]
error:
<ERROR> NEXT:[] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<END>]
=====================
== inner_bar ==
fun inner_bar() {
y = 10
}
---------------------
l3:
<START> NEXT:[r(10)] PREV:[]
r(10) NEXT:[w(y)] PREV:[<START>]
w(y) NEXT:[<END>] PREV:[r(10)]
l4:
<END> NEXT:[<SINK>] PREV:[w(y)]
error:
<ERROR> NEXT:[] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<END>]
=====================
== test3 ==
fun test3() {
val a = object {
val y : Int
fun inner_bar() {
y = 10
}
}
}
---------------------
l0:
<START> NEXT:[jmp?(l2)] PREV:[]
jmp?(l2) NEXT:[r(object { val y : Int fun i..), df(fun inner_bar() { y = 10 ..)] PREV:[<START>]
df(fun inner_bar() {
y = 10
}) NEXT:[<SINK>] PREV:[jmp?(l2)]
l2:
r(object {
val y : Int
fun inner_bar() {
y = 10
}
}) NEXT:[w(a)] PREV:[jmp?(l2)]
w(a) NEXT:[<END>] PREV:[r(object { val y : Int fun i..)]
l1:
<END> NEXT:[<SINK>] PREV:[w(a)]
error:
<ERROR> NEXT:[] PREV:[]
sink:
<SINK> NEXT:[] PREV:[df(fun inner_bar() { y = 10 ..), <END>]
l3:
<START> NEXT:[r(10)] PREV:[]
r(10) NEXT:[w(y)] PREV:[<START>]
w(y) NEXT:[<END>] PREV:[r(10)]
l4:
<END> NEXT:[<SINK>] PREV:[w(y)]
error:
<ERROR> NEXT:[] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<END>]
=====================
== ggg ==
fun ggg() {
y = 10
}
---------------------
l3:
<START> NEXT:[r(10)] PREV:[]
r(10) NEXT:[w(y)] PREV:[<START>]
w(y) NEXT:[<END>] PREV:[r(10)]
l4:
<END> NEXT:[<SINK>] PREV:[w(y)]
error:
<ERROR> NEXT:[] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<END>]
=====================
== test4 ==
fun test4() {
val a = object {
val x : Int
val y : Int
{
$x = 1
}
fun ggg() {
y = 10
}
}
}
---------------------
l0:
<START> NEXT:[r(1)] PREV:[]
r(1) NEXT:[w($x)] PREV:[<START>]
w($x) NEXT:[jmp?(l2)] PREV:[r(1)]
jmp?(l2) NEXT:[r(object { val x : Int val y..), df(fun ggg() { y = 10 }) ] PREV:[w($x)]
df(fun ggg() {
y = 10
}) NEXT:[<SINK>] PREV:[jmp?(l2)]
l2:
r(object {
val x : Int
val y : Int
{
$x = 1
}
fun ggg() {
y = 10
}
}) NEXT:[w(a)] PREV:[jmp?(l2)]
w(a) NEXT:[<END>] PREV:[r(object { val x : Int val y..)]
l1:
<END> NEXT:[<SINK>] PREV:[w(a)]
error:
<ERROR> NEXT:[] PREV:[]
sink:
<SINK> NEXT:[] PREV:[df(fun ggg() { y = 10 }) , <END>]
l3:
<START> NEXT:[r(10)] PREV:[]
r(10) NEXT:[w(y)] PREV:[<START>]
w(y) NEXT:[<END>] PREV:[r(10)]
l4:
<END> NEXT:[<SINK>] PREV:[w(y)]
error:
<ERROR> NEXT:[] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<END>]
=====================
== foo ==
fun foo() {
x = 3
}
---------------------
l3:
<START> NEXT:[r(3)] PREV:[]
r(3) NEXT:[w(x)] PREV:[<START>]
w(x) NEXT:[<END>] PREV:[r(3)]
l4:
<END> NEXT:[<SINK>] PREV:[w(x)]
error:
<ERROR> NEXT:[] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<END>]
=====================
== bar ==
fun bar() {
x = 4
}
---------------------
l6:
<START> NEXT:[r(4)] PREV:[]
r(4) NEXT:[w(x)] PREV:[<START>]
w(x) NEXT:[<END>] PREV:[r(4)]
l7:
<END> NEXT:[<SINK>] PREV:[w(x)]
error:
<ERROR> NEXT:[] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<END>]
=====================
== test5 ==
fun test5() {
val a = object {
var x = 1
{
$x = 2
}
fun foo() {
x = 3
}
fun bar() {
x = 4
}
}
}
---------------------
l0:
<START> NEXT:[r(1)] PREV:[]
r(1) NEXT:[w(x)] PREV:[<START>]
w(x) NEXT:[r(2)] PREV:[r(1)]
r(2) NEXT:[w($x)] PREV:[w(x)]
w($x) NEXT:[jmp?(l2)] PREV:[r(2)]
jmp?(l2) NEXT:[jmp?(l5), df(fun foo() { x = 3 }) ] PREV:[w($x)]
df(fun foo() {
x = 3
}) NEXT:[<SINK>] PREV:[jmp?(l2)]
l2:
jmp?(l5) NEXT:[r(object { var x = 1 { $x = ..), df(fun bar() { x = 4 }) ] PREV:[jmp?(l2)]
df(fun bar() {
x = 4
}) NEXT:[<SINK>] PREV:[jmp?(l5)]
l5:
r(object {
var x = 1
{
$x = 2
}
fun foo() {
x = 3
}
fun bar() {
x = 4
}
}) NEXT:[w(a)] PREV:[jmp?(l5)]
w(a) NEXT:[<END>] PREV:[r(object { var x = 1 { $x = ..)]
l1:
<END> NEXT:[<SINK>] PREV:[w(a)]
error:
<ERROR> NEXT:[] PREV:[]
sink:
<SINK> NEXT:[] PREV:[df(fun foo() { x = 3 }) , df(fun bar() { x = 4 }) , <END>]
l3:
<START> NEXT:[r(3)] PREV:[]
r(3) NEXT:[w(x)] PREV:[<START>]
w(x) NEXT:[<END>] PREV:[r(3)]
l4:
<END> NEXT:[<SINK>] PREV:[w(x)]
error:
<ERROR> NEXT:[] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<END>]
l6:
<START> NEXT:[r(4)] PREV:[]
r(4) NEXT:[w(x)] PREV:[<START>]
w(x) NEXT:[<END>] PREV:[r(4)]
l7:
<END> NEXT:[<SINK>] PREV:[w(x)]
error:
<ERROR> NEXT:[] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<END>]
=====================
== foo ==
fun foo() {
val b : Int = 1
doSmth(b)
}
---------------------
l0:
<START> NEXT:[r(1)] PREV:[]
r(1) NEXT:[w(b)] PREV:[<START>]
w(b) NEXT:[r(b)] PREV:[r(1)]
r(b) NEXT:[r(doSmth)] PREV:[w(b)]
r(doSmth) NEXT:[r(doSmth(b))] PREV:[r(b)]
r(doSmth(b)) NEXT:[<END>] PREV:[r(doSmth)]
l1:
<END> NEXT:[<SINK>] PREV:[r(doSmth(b))]
error:
<ERROR> NEXT:[] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<END>]
=====================
== a ==
val a: Int = 1
---------------------
l0:
<START> NEXT:[r(1)] PREV:[]
r(1) NEXT:[<END>] PREV:[<START>]
l1:
<END> NEXT:[<SINK>] PREV:[r(1)]
error:
<ERROR> NEXT:[] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<END>]
=====================
@@ -0,0 +1,77 @@
class C() {
val a: Int = 1
class object {
val x : Int
{
$x = 1
}
fun foo() {
val b : Int = 1
doSmth(b)
}
}
}
fun doSmth(i: Int) {}
fun test1() {
val a = object {
val x : Int
{
$x = 1
}
}
}
object O {
val x : Int
{
$x = 1
}
}
fun test2() {
val b = 1
val a = object {
val x = b
}
}
fun test3() {
val a = object {
val y : Int
fun inner_bar() {
y = 10
}
}
}
fun test4() {
val a = object {
val x : Int
val y : Int
{
$x = 1
}
fun ggg() {
y = 10
}
}
}
fun test5() {
val a = object {
var x = 1
{
$x = 2
}
fun foo() {
x = 3
}
fun bar() {
x = 4
}
}
}
@@ -269,17 +269,45 @@ fun foo() {
val a = object {
val x : Int
val <!MUST_BE_INITIALIZED_OR_BE_ABSTRACT!>y<!> : Int
val z : Int
{
$x = 1
$z = 3
}
fun foo() {
<!VAL_REASSIGNMENT!>y<!> = 10
<!VAL_REASSIGNMENT!>z<!> = 13
}
//todo
/* fun foo() {
<VAL_REASSIGNMENT>y<> = 10
}*/
}
}
object O {
class TestObjectExpression() {
val <!MUST_BE_INITIALIZED_OR_BE_ABSTRACT!>a<!> : Int
fun foo() {
val a = object {
val x : Int
val <!MUST_BE_INITIALIZED_OR_BE_ABSTRACT!>y<!> : Int
{
if (true)
<!INITIALIZATION_USING_BACKING_FIELD!>x<!> = 12
else
$x = 1
}
fun inner1() {
<!VAL_REASSIGNMENT!>y<!> = 101
<!VAL_REASSIGNMENT!>a<!> = 231
}
fun inner2() {
<!VAL_REASSIGNMENT!>y<!> = 101
<!VAL_REASSIGNMENT!>a<!> = 231
}
}
}
}
object TestObjectDeclaration {
val x : Int
val <!MUST_BE_INITIALIZED_OR_BE_ABSTRACT!>y<!> : Int
{
@@ -296,7 +324,7 @@ object O {
}
}
fun foo() {
fun func() {
val b = 1
val a = object {
val x = b
@@ -275,7 +275,7 @@ public class JetControlFlowTest extends JetLiteFixture {
@Override
public void visitUnconditionalJump(UnconditionalJumpInstruction instruction) {
// Nothing
printEdge(out, nodeToName.get(instruction), nodeToName.get(instruction.getResolvedTarget()), null);
}
@Override
@@ -334,9 +334,6 @@ public class JetControlFlowTest extends JetLiteFixture {
public void dumpNodes(List<Instruction> instructions, PrintStream out, int[] count, Map<Instruction, String> nodeToName) {
for (Instruction node : instructions) {
if (node instanceof UnconditionalJumpInstruction) {
continue;
}
String name = "n" + count[0]++;
nodeToName.put(node, name);
String text = node.toString();
@@ -345,7 +342,7 @@ public class JetControlFlowTest extends JetLiteFixture {
text = text.substring(0, newline);
}
String shape = "box";
if (node instanceof ConditionalJumpInstruction) {
if (node instanceof ConditionalJumpInstruction || node instanceof UnconditionalJumpInstruction) {
shape = "diamond";
}
else if (node instanceof NondeterministicJumpInstruction) {