Bug 202393

Summary: [compiler] Incomplete code coverage or useless statement within ThrowStatement#resolve
Product: [Eclipse Project] JDT Reporter: Maxime Daniel <maxime_daniel>
Component: CoreAssignee: Philipe Mulet <philippe_mulet>
Status: VERIFIED FIXED QA Contact:
Severity: normal    
Priority: P3 CC: philippe_mulet, stephan.herrmann
Version: 3.4   
Target Milestone: 3.5 M6   
Hardware: PC   
OS: Linux   
Whiteboard:

Description Maxime Daniel CLA 2007-09-06 03:31:39 EDT
Code based, v_810.
The 'this.exception.computeConversion(scope, this.exceptionType, this.exceptionType);' statement in ThrowStatement#resolve can be commented out without tilting any JDT Core test case. This implies that either the statement is unneeded, or the test suite should be augmented. I have not investigated which of these is the right option (got alerted by the fact that a peculiar step-through was obviously doing nothing at all, but this does not prove that the statement is useless).
Comment 1 Stephan Herrmann CLA 2008-09-01 18:04:50 EDT
Looking at the code it is very tempting to say, the mentioned line
will never do any useful stuff, but:

public class C {
    static <T> T id(T in) { return in; }
    public static void main(String[] args) throws Throwable {
        throw id(new Exception());
    }
}

this compiles with and without the line in question, however,
executing the class in one case yields:

Exception in thread "main" java.lang.Exception
        at C.main(C.java:4)

in the other case you get:

Exception in thread "main" java.lang.VerifyError: (class: C, method: main signature: ([Ljava/lang/String;)V) Can only throw Throwable objects

(You may guess which is which ;-)
Comment 2 Stephan Herrmann CLA 2009-01-20 12:20:35 EST
Here's a snippet that tests the line in question:

// https://bugs.eclipse.org/bugs/show_bug.cgi?id=202393
// improve coverage of tests.
public void test0701_legalByteCode() {
	if (this.complianceLevel < ClassFileConstants.JDK1_5)
		return;
	this.runConformTest(
		new String[] {
			"Bug202393.java",
			"public class Bug202393 {\n" + 
			"   static <T> T id(T in) { return in; }\n" +
			"   public static void main(String[] args) {\n" +
			"      try {" +
			"         bad();" +
			"      } catch (Throwable t) {\n" +
			"         System.out.print(\"CAUGHT\");\n" +
			"      }\n" +
			"   }\n" +
			"   static void bad() throws Throwable {\n" +
			"      throw id(new Exception());\n" +
			"   }\n" +
			"}\n"},
		"CAUGHT"
	);
}

I placed it in org.eclipse.jdt.core.tests.compiler.regression.RuntimeTests
and it indeed fails if the line in ThrowStatement is deleted.
Is there a better place to test for legal byte code?
A better way to handle the <1.5 case?
Comment 3 Philipe Mulet CLA 2009-02-03 06:48:44 EST
Thanks Stephan, indeed the line is needed to perform conversions such as generic ones.
Comment 4 Philipe Mulet CLA 2009-02-03 06:51:38 EST
Released the new test as GenericTypeTest#test1446, into 3.5M6.
Fixed
Comment 5 Kent Johnson CLA 2009-03-10 10:16:22 EDT
Verified for 3.5M6 using I20090310-0100