Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
View | Details | Raw Unified | Return to bug 190209
Collapse All | Expand All

(-)compiler/org/eclipse/jdt/internal/compiler/ast/ReturnStatement.java (-4 / +8 lines)
Lines 44-52 Link Here
44
	FlowContext traversedContext = flowContext;
44
	FlowContext traversedContext = flowContext;
45
	int subCount = 0;
45
	int subCount = 0;
46
	boolean saveValueNeeded = false;
46
	boolean saveValueNeeded = false;
47
	boolean hasValueToSave = this.expression != null 
47
	boolean hasValueToSave = needValueStore();
48
						&& this.expression.constant == Constant.NotAConstant 
49
						&& !(this.expression instanceof NullLiteral);
50
	do {
48
	do {
51
		SubRoutineStatement sub;
49
		SubRoutineStatement sub;
52
		if ((sub = traversedContext.subroutine()) != null) {
50
		if ((sub = traversedContext.subroutine()) != null) {
Lines 119-125 Link Here
119
	int pc = codeStream.position;
117
	int pc = codeStream.position;
120
	boolean alreadyGeneratedExpression = false;
118
	boolean alreadyGeneratedExpression = false;
121
	// generate the expression
119
	// generate the expression
122
	if ((this.expression != null) && (this.expression.constant == Constant.NotAConstant) && !(this.expression instanceof NullLiteral)) {
120
	if (needValueStore()) {
123
		alreadyGeneratedExpression = true;
121
		alreadyGeneratedExpression = true;
124
		this.expression.generateCode(currentScope, codeStream, needValue()); // no value needed if non-returning subroutine
122
		this.expression.generateCode(currentScope, codeStream, needValue()); // no value needed if non-returning subroutine
125
		generateStoreSaveValueIfNecessary(codeStream);
123
		generateStoreSaveValueIfNecessary(codeStream);
Lines 173-178 Link Here
173
	}
171
	}
174
}
172
}
175
173
174
private boolean needValueStore() {
175
	return this.expression != null 
176
					&& (this.expression.constant == Constant.NotAConstant || (this.expression.implicitConversion & TypeIds.BOXING)!= 0)
177
					&& !(this.expression instanceof NullLiteral);
178
}
179
176
public boolean needValue() {
180
public boolean needValue() {
177
	return this.saveValueVariable != null 
181
	return this.saveValueVariable != null 
178
					|| (this.bits & ASTNode.IsSynchronized) != 0
182
					|| (this.bits & ASTNode.IsSynchronized) != 0
(-)compiler/org/eclipse/jdt/internal/compiler/ast/SubRoutineStatement.java (+9 lines)
Lines 56-61 Link Here
56
	}
56
	}
57
	
57
	
58
58
59
	/**
60
	 * Generate an invocation of a subroutine (e.g. jsr finally) in current context.
61
	 * @param currentScope
62
	 * @param codeStream
63
	 * @param targetLocation
64
	 * @param stateIndex
65
	 * @param secretLocal
66
	 * @return boolean, <code>true</code> if the generated code will abrupt completion
67
	 */
59
	public abstract boolean generateSubRoutineInvocation(BlockScope currentScope, CodeStream codeStream, Object targetLocation, int stateIndex, LocalVariableBinding secretLocal);	
68
	public abstract boolean generateSubRoutineInvocation(BlockScope currentScope, CodeStream codeStream, Object targetLocation, int stateIndex, LocalVariableBinding secretLocal);	
60
	
69
	
61
	public abstract boolean isSubRoutineEscaping();
70
	public abstract boolean isSubRoutineEscaping();
(-)src/org/eclipse/jdt/core/tests/compiler/regression/TryStatementTest.java (+340 lines)
Lines 5488-5493 Link Here
5488
		"No exception of type int can be thrown; an exception type must be a subclass of Throwable\n" + 
5488
		"No exception of type int can be thrown; an exception type must be a subclass of Throwable\n" + 
5489
		"----------\n");
5489
		"----------\n");
5490
}
5490
}
5491
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=190209 - variation
5492
public void test062() {
5493
	if (new CompilerOptions(this.getCompilerOptions()).complianceLevel < ClassFileConstants.JDK1_5) return; // need autoboxing
5494
	this.runConformTest(
5495
			new String[] {
5496
				"X.java",
5497
				"final public class X {\n" + 
5498
				"	final class MyClass {\n" + 
5499
				"		/** @param s */\n" + 
5500
				"		void foo(final String s) {\n" + 
5501
				"			 /* do nothing */\n" + 
5502
				"		}\n" + 
5503
				"	}\n" + 
5504
				"	Object bar() {\n" + 
5505
				"		try {\n" + 
5506
				"			final MyClass myClass = new MyClass();\n" + 
5507
				"			try {\n" + 
5508
				"				return 0;\n" + 
5509
				"			} catch (final Throwable ex) {\n" + 
5510
				"				myClass.foo(this == null ? \"\" : \"\");\n" + 
5511
				"			}\n" + 
5512
				"	\n" + 
5513
				"			return this;\n" + 
5514
				"		} finally {\n" + 
5515
				"			{ /* do nothing */ }\n" + 
5516
				"		}\n" + 
5517
				"	}\n" + 
5518
				"	public static void main(String[] args) {\n" + 
5519
				"		new X().bar();\n" + 
5520
				"		System.out.print(\"SUCCESS\");\n" + 
5521
				"	}\n" + 
5522
				"}\n",
5523
			},
5524
			"SUCCESS");
5525
	
5526
	String expectedOutput = 
5527
			"  // Method descriptor #15 ()Ljava/lang/Object;\n" + 
5528
			"  // Stack: 3, Locals: 5\n" + 
5529
			"  java.lang.Object bar();\n" + 
5530
			"     0  new X$MyClass [16]\n" + 
5531
			"     3  dup\n" + 
5532
			"     4  aload_0 [this]\n" + 
5533
			"     5  invokespecial X$MyClass(X) [18]\n" + 
5534
			"     8  astore_1 [myClass]\n" + 
5535
			"     9  iconst_0\n" + 
5536
			"    10  invokestatic java.lang.Integer.valueOf(int) : java.lang.Integer [21]\n" + 
5537
			"    13  astore 4\n" + 
5538
			"    15  aload 4\n" + 
5539
			"    17  areturn\n" + 
5540
			"    18  astore_2 [ex]\n" + 
5541
			"    19  aload_1 [myClass]\n" + 
5542
			"    20  aload_0 [this]\n" + 
5543
			"    21  ifnonnull 29\n" + 
5544
			"    24  ldc <String \"\"> [27]\n" + 
5545
			"    26  goto 31\n" + 
5546
			"    29  ldc <String \"\"> [27]\n" + 
5547
			"    31  invokevirtual X$MyClass.foo(java.lang.String) : void [29]\n" + 
5548
			"    34  aload_0 [this]\n" + 
5549
			"    35  astore 4\n" + 
5550
			"    37  aload 4\n" + 
5551
			"    39  areturn\n" + 
5552
			"    40  astore_3\n" + 
5553
			"    41  aload_3\n" + 
5554
			"    42  athrow\n" + 
5555
			"      Exception Table:\n" + 
5556
			"        [pc: 9, pc: 15] -> 18 when : java.lang.Throwable\n" + 
5557
			"        [pc: 0, pc: 15] -> 40 when : any\n" + 
5558
			"        [pc: 18, pc: 37] -> 40 when : any\n";
5559
	
5560
	try {
5561
		File f = new File(OUTPUT_DIR + File.separator + "X.class");
5562
		byte[] classFileBytes = org.eclipse.jdt.internal.compiler.util.Util.getFileByteContent(f);
5563
		ClassFileBytesDisassembler disassembler = ToolFactory.createDefaultClassFileBytesDisassembler();
5564
		String result = disassembler.disassemble(classFileBytes, "\n", ClassFileBytesDisassembler.DETAILED);
5565
		int index = result.indexOf(expectedOutput);
5566
		if (index == -1 || expectedOutput.length() == 0) {
5567
			System.out.println(Util.displayString(result, 3));
5568
		}
5569
		if (index == -1) {
5570
			assertEquals("Wrong contents", expectedOutput, result);
5571
		}
5572
	} catch (org.eclipse.jdt.core.util.ClassFormatException e) {
5573
		assertTrue(false);
5574
	} catch (IOException e) {
5575
		assertTrue(false);
5576
	}	
5577
}
5578
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=190209 - variation
5579
public void test063() {
5580
	this.runConformTest(
5581
			new String[] {
5582
				"X.java",
5583
				"final public class X {\n" + 
5584
				"	final class MyClass {\n" + 
5585
				"		/** @param s */\n" + 
5586
				"		void foo(final String s) {\n" + 
5587
				"			 /* do nothing */\n" + 
5588
				"		}\n" + 
5589
				"	}\n" + 
5590
				"	void bar() {\n" + 
5591
				"		try {\n" + 
5592
				"			final MyClass myClass = new MyClass();\n" + 
5593
				"			try {\n" + 
5594
				"				return;\n" + 
5595
				"			} catch (final Throwable ex) {\n" + 
5596
				"				myClass.foo(this == null ? \"\" : \"\");\n" + 
5597
				"			}\n" + 
5598
				"			return;\n" + 
5599
				"		} finally {\n" + 
5600
				"			{ /* do nothing */ }\n" + 
5601
				"		}\n" + 
5602
				"	}\n" + 
5603
				"	public static void main(String[] args) {\n" + 
5604
				"		new X().bar();\n" + 
5605
				"		System.out.print(\"SUCCESS\");\n" + 
5606
				"	}\n" + 
5607
				"}\n",
5608
			},
5609
			"SUCCESS");
5610
	
5611
	String expectedOutput = new CompilerOptions(this.getCompilerOptions()).complianceLevel <= ClassFileConstants.JDK1_4
5612
		?	"  // Method descriptor #6 ()V\n" + 
5613
			"  // Stack: 3, Locals: 5\n" + 
5614
			"  void bar();\n" + 
5615
			"     0  new X$MyClass [15]\n" + 
5616
			"     3  dup\n" + 
5617
			"     4  aload_0 [this]\n" + 
5618
			"     5  invokespecial X$MyClass(X) [17]\n" + 
5619
			"     8  astore_1 [myClass]\n" + 
5620
			"     9  jsr 40\n" + 
5621
			"    12  return\n" + 
5622
			"    13  astore_2 [ex]\n" + 
5623
			"    14  aload_1 [myClass]\n" + 
5624
			"    15  aload_0 [this]\n" + 
5625
			"    16  ifnonnull 24\n" + 
5626
			"    19  ldc <String \"\"> [20]\n" + 
5627
			"    21  goto 26\n" + 
5628
			"    24  ldc <String \"\"> [20]\n" + 
5629
			"    26  invokevirtual X$MyClass.foo(java.lang.String) : void [22]\n" + 
5630
			"    29  goto 9\n" + 
5631
			"    32  astore 4\n" + 
5632
			"    34  jsr 40\n" + 
5633
			"    37  aload 4\n" + 
5634
			"    39  athrow\n" + 
5635
			"    40  astore_3\n" + 
5636
			"    41  ret 3\n" + 
5637
			"      Exception Table:\n" + 
5638
			"        [pc: 0, pc: 12] -> 32 when : any\n" + 
5639
			"        [pc: 13, pc: 32] -> 32 when : any\n"
5640
		:	
5641
			"  // Method descriptor #6 ()V\n" + 
5642
			"  // Stack: 3, Locals: 4\n" + 
5643
			"  void bar();\n" + 
5644
			"     0  new X$MyClass [15]\n" + 
5645
			"     3  dup\n" + 
5646
			"     4  aload_0 [this]\n" + 
5647
			"     5  invokespecial X$MyClass(X) [17]\n" + 
5648
			"     8  astore_1 [myClass]\n" + 
5649
			"     9  return\n" + 
5650
			"    10  astore_2 [ex]\n" + 
5651
			"    11  aload_1 [myClass]\n" + 
5652
			"    12  aload_0 [this]\n" + 
5653
			"    13  ifnonnull 21\n" + 
5654
			"    16  ldc <String \"\"> [20]\n" + 
5655
			"    18  goto 23\n" + 
5656
			"    21  ldc <String \"\"> [20]\n" + 
5657
			"    23  invokevirtual X$MyClass.foo(java.lang.String) : void [22]\n" + 
5658
			"    26  goto 9\n" + 
5659
			"    29  astore_3\n" + 
5660
			"    30  aload_3\n" + 
5661
			"    31  athrow\n" + 
5662
			"      Exception Table:\n" + 
5663
			"        [pc: 0, pc: 9] -> 29 when : any\n" + 
5664
			"        [pc: 10, pc: 29] -> 29 when : any\n";
5665
	
5666
	try {
5667
		File f = new File(OUTPUT_DIR + File.separator + "X.class");
5668
		byte[] classFileBytes = org.eclipse.jdt.internal.compiler.util.Util.getFileByteContent(f);
5669
		ClassFileBytesDisassembler disassembler = ToolFactory.createDefaultClassFileBytesDisassembler();
5670
		String result = disassembler.disassemble(classFileBytes, "\n", ClassFileBytesDisassembler.DETAILED);
5671
		int index = result.indexOf(expectedOutput);
5672
		if (index == -1 || expectedOutput.length() == 0) {
5673
			System.out.println(Util.displayString(result, 3));
5674
		}
5675
		if (index == -1) {
5676
			assertEquals("Wrong contents", expectedOutput, result);
5677
		}
5678
	} catch (org.eclipse.jdt.core.util.ClassFormatException e) {
5679
		assertTrue(false);
5680
	} catch (IOException e) {
5681
		assertTrue(false);
5682
	}	
5683
}
5684
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=190209 - variation
5685
public void test064() {
5686
	this.runConformTest(
5687
			new String[] {
5688
				"X.java",
5689
				"final public class X {\n" + 
5690
				"	final class MyClass {\n" + 
5691
				"		/** @param s */\n" + 
5692
				"		void foo(final String s) {\n" + 
5693
				"			 /* do nothing */\n" + 
5694
				"		}\n" + 
5695
				"	}\n" + 
5696
				"	Object bar() {\n" + 
5697
				"		try {\n" + 
5698
				"			final MyClass myClass = new MyClass();\n" + 
5699
				"			try {\n" + 
5700
				"				return null;\n" + 
5701
				"			} catch (final Throwable ex) {\n" + 
5702
				"				myClass.foo(this == null ? \"\" : \"\");\n" + 
5703
				"			}\n" + 
5704
				"			return null;\n" + 
5705
				"		} finally {\n" + 
5706
				"			{ /* do nothing */ }\n" + 
5707
				"		}\n" + 
5708
				"	}\n" + 
5709
				"	public static void main(String[] args) {\n" + 
5710
				"		new X().bar();\n" + 
5711
				"		System.out.print(\"SUCCESS\");\n" + 
5712
				"	}\n" + 
5713
				"}\n",
5714
			},
5715
			"SUCCESS");
5716
	
5717
	String expectedOutput = new CompilerOptions(this.getCompilerOptions()).complianceLevel <= ClassFileConstants.JDK1_4
5718
		?	"  // Method descriptor #15 ()Ljava/lang/Object;\n" + 
5719
			"  // Stack: 3, Locals: 5\n" + 
5720
			"  java.lang.Object bar();\n" + 
5721
			"     0  new X$MyClass [16]\n" + 
5722
			"     3  dup\n" + 
5723
			"     4  aload_0 [this]\n" + 
5724
			"     5  invokespecial X$MyClass(X) [18]\n" + 
5725
			"     8  astore_1 [myClass]\n" + 
5726
			"     9  jsr 41\n" + 
5727
			"    12  aconst_null\n" + 
5728
			"    13  areturn\n" + 
5729
			"    14  astore_2 [ex]\n" + 
5730
			"    15  aload_1 [myClass]\n" + 
5731
			"    16  aload_0 [this]\n" + 
5732
			"    17  ifnonnull 25\n" + 
5733
			"    20  ldc <String \"\"> [21]\n" + 
5734
			"    22  goto 27\n" + 
5735
			"    25  ldc <String \"\"> [21]\n" + 
5736
			"    27  invokevirtual X$MyClass.foo(java.lang.String) : void [23]\n" + 
5737
			"    30  goto 9\n" + 
5738
			"    33  astore 4\n" + 
5739
			"    35  jsr 41\n" + 
5740
			"    38  aload 4\n" + 
5741
			"    40  athrow\n" + 
5742
			"    41  astore_3\n" + 
5743
			"    42  ret 3\n" + 
5744
			"      Exception Table:\n" + 
5745
			"        [pc: 0, pc: 12] -> 33 when : any\n" + 
5746
			"        [pc: 14, pc: 33] -> 33 when : any\n"
5747
		:	
5748
			"  // Method descriptor #15 ()Ljava/lang/Object;\n" + 
5749
			"  // Stack: 3, Locals: 4\n" + 
5750
			"  java.lang.Object bar();\n" + 
5751
			"     0  new X$MyClass [16]\n" + 
5752
			"     3  dup\n" + 
5753
			"     4  aload_0 [this]\n" + 
5754
			"     5  invokespecial X$MyClass(X) [18]\n" + 
5755
			"     8  astore_1 [myClass]\n" + 
5756
			"     9  aconst_null\n" + 
5757
			"    10  areturn\n" + 
5758
			"    11  astore_2 [ex]\n" + 
5759
			"    12  aload_1 [myClass]\n" + 
5760
			"    13  aload_0 [this]\n" + 
5761
			"    14  ifnonnull 22\n" + 
5762
			"    17  ldc <String \"\"> [21]\n" + 
5763
			"    19  goto 24\n" + 
5764
			"    22  ldc <String \"\"> [21]\n" + 
5765
			"    24  invokevirtual X$MyClass.foo(java.lang.String) : void [23]\n" + 
5766
			"    27  goto 9\n" + 
5767
			"    30  astore_3\n" + 
5768
			"    31  aload_3\n" + 
5769
			"    32  athrow\n" + 
5770
			"      Exception Table:\n" + 
5771
			"        [pc: 0, pc: 9] -> 30 when : any\n" + 
5772
			"        [pc: 11, pc: 30] -> 30 when : any\n";
5773
	
5774
	try {
5775
		File f = new File(OUTPUT_DIR + File.separator + "X.class");
5776
		byte[] classFileBytes = org.eclipse.jdt.internal.compiler.util.Util.getFileByteContent(f);
5777
		ClassFileBytesDisassembler disassembler = ToolFactory.createDefaultClassFileBytesDisassembler();
5778
		String result = disassembler.disassemble(classFileBytes, "\n", ClassFileBytesDisassembler.DETAILED);
5779
		int index = result.indexOf(expectedOutput);
5780
		if (index == -1 || expectedOutput.length() == 0) {
5781
			System.out.println(Util.displayString(result, 3));
5782
		}
5783
		if (index == -1) {
5784
			assertEquals("Wrong contents", expectedOutput, result);
5785
		}
5786
	} catch (org.eclipse.jdt.core.util.ClassFormatException e) {
5787
		assertTrue(false);
5788
	} catch (IOException e) {
5789
		assertTrue(false);
5790
	}	
5791
}
5792
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=191865
5793
public void test065() {
5794
	this.runNegativeTest(
5795
		new String[] {
5796
			"X.java",
5797
			"public class X {\n" + 
5798
			"	void foo() {\n" + 
5799
			"		try {\n" + 
5800
			"			System.out.println(\"Hello\");\n" + 
5801
			"		} finally {\n" + 
5802
			"			if (true)\n" + 
5803
			"				return;\n" + 
5804
			"		}\n" + 
5805
			"		return;\n" + 
5806
			"	}\n" + 
5807
			"	void bar() {\n" + 
5808
			"		try {\n" + 
5809
			"			System.out.println(\"Hello\");\n" + 
5810
			"		} finally {\n" + 
5811
			"			return;\n" + 
5812
			"		}\n" + 
5813
			"		return;\n" + 
5814
			"	}\n" + 
5815
			"}\n",
5816
		},
5817
		"----------\n" + 
5818
		"1. WARNING in X.java (at line 14)\n" + 
5819
		"	} finally {\n" + 
5820
		"			return;\n" + 
5821
		"		}\n" + 
5822
		"	          ^^^^^^^^^^^^^^^^\n" + 
5823
		"finally block does not complete normally\n" + 
5824
		"----------\n" + 
5825
		"2. ERROR in X.java (at line 17)\n" + 
5826
		"	return;\n" + 
5827
		"	^^^^^^^\n" + 
5828
		"Unreachable code\n" + 
5829
		"----------\n");
5830
}
5491
public static Class testClass() {
5831
public static Class testClass() {
5492
	return TryStatementTest.class;
5832
	return TryStatementTest.class;
5493
}
5833
}

Return to bug 190209