Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 421543 - [1.8][compiler] Compiler fails to recognize default method being turned into abstract by subtytpe
Summary: [1.8][compiler] Compiler fails to recognize default method being turned into ...
Status: RESOLVED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 4.4   Edit
Hardware: PC Windows 7
: P3 normal (vote)
Target Milestone: BETA J8   Edit
Assignee: Stephan Herrmann CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks: 380501
  Show dependency tree
 
Reported: 2013-11-12 10:57 EST by Srikanth Sankaran CLA
Modified: 2013-11-19 14:01 EST (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Srikanth Sankaran CLA 2013-11-12 10:57:02 EST
BETA_JAVA8:

The following program correctly triggers an error: 

The type X must implement the inherited abstract method J.foo()

// --
interface I  {
	default void foo() {}
}

interface J extends I {
	void foo();
}
public class X implements J {
}

However, if the types are generic, we don't issue an error:

// --
interface I <T> {
	default void foo(T t) {}
}

interface J extends I<J> {
	void foo(J t);
}
public class X implements J {
}
Comment 1 Srikanth Sankaran CLA 2013-11-12 11:04:23 EST
I released two regressions tests (one disabled) here: http://git.eclipse.org/c/jdt/eclipse.jdt.core.git/commit/?h=BETA_JAVA8&id=58f7143be75deb274bc31e6b1b222d6530d0388b

I'll take a quick look and if it is not too involved, will fix it myself.
Otherwise, will assign to Stephan.
Comment 2 Srikanth Sankaran CLA 2013-11-12 11:58:55 EST
(In reply to Srikanth Sankaran from comment #1)

> I'll take a quick look and if it is not too involved, will fix it myself.
> Otherwise, will assign to Stephan.

Stephan, thanks for taking a look. You have much more current familiarity
with this piece.
Comment 3 Srikanth Sankaran CLA 2013-11-12 20:25:48 EST
(In reply to Srikanth Sankaran from comment #2)

> Stephan, thanks for taking a look. You have much more current familiarity
> with this piece.

Alternately, if you can tell me what the values for

skip[], isOverridden[] and isInherited[] are supposed to be given a
MethodBinding[] of [ default void foo(), abstract void foo() ] I can
continue to work on it too.

I think these should be

skip [] = [true, false]
isOverridden [] = [true, false]
isInherited[true, true]

Is that correct ?
Comment 4 Srikanth Sankaran CLA 2013-11-13 04:48:46 EST
I also released an additional disabled test org.eclipse.jdt.core.tests.compiler.regression.InterfaceMethodsTest._testBug421543b()
that shows two problems. Bridge method is getting emitted in X it could be 
emitted in J for efficiency reasons.

Also the compiled file triggers a verify error. Constant pool entry
contains MethodRef instead of InterfaceMethodRef. Also should be using
invokeInterface instead of invokespecial ?
Comment 5 Stephan Herrmann CLA 2013-11-14 05:40:36 EST
I'll take a look today.
Comment 6 Srikanth Sankaran CLA 2013-11-14 05:43:05 EST
I notice that MV15.isSkippableOrOverridden calls isInterfaceMethodImplemented()
which carries a caveat: "returns false if a method is implemented that needs a 
bridge method" - That is basically a broken API. Something to be wary of.
  

(In reply to Stephan Herrmann from comment #5)
> I'll take a look today.

Thanks!
Comment 7 Stephan Herrmann CLA 2013-11-14 07:31:29 EST
Experiments indicate that fixing this may introduce a secondary error
in InterfaceMethodsTest.testBridge01:

2. ERROR in PurebredCatShopImpl.java (at line 8)
	interface PurebredCatShop extends CatShop {}
	          ^^^^^^^^^^^^^^^
Duplicate methods named getPets with the parameters () and () are defined by the type CatShop

The primary error is (in class CatShop):

1. ERROR in PurebredCatShopImpl.java (at line 6)
	default <V extends Pet> List<? extends Cat> getPets() { return null; }
	                                            ^^^^^^^^^
Name clash: The method getPets() of type CatShop has the same erasure as getPets() of type PetShop but does not override it

Do you think the secondary error is acceptable?
Comment 8 Stephan Herrmann CLA 2013-11-14 07:39:49 EST
(In reply to Stephan Herrmann from comment #7)
> Experiments indicate that fixing this may introduce a secondary error
> in InterfaceMethodsTest.testBridge01:

Probably a red herring. Properly applying the patch from bug 410325
seems to be all we need for the problem in comment 0.
Comment 9 Srikanth Sankaran CLA 2013-11-14 08:08:38 EST
(In reply to Stephan Herrmann from comment #8)

> Probably a red herring. Properly applying the patch from bug 410325
> seems to be all we need for the problem in comment 0.

Did you mean there was a problem in cherry picking this commit ? 
I searched through several pages of commit logs on BETA_JAVA8
branch and don't see the commit for bug 410325 at all.

Jay, what would explain this ? Did we ever selective cherry pick from master ??
Comment 10 Stephan Herrmann CLA 2013-11-14 08:47:13 EST
(In reply to Srikanth Sankaran from comment #4)
> I also released an additional disabled test
> org.eclipse.jdt.core.tests.compiler.regression.InterfaceMethodsTest.
> _testBug421543b()
> that shows two problems. Bridge method is getting emitted in X it could be 
> emitted in J for efficiency reasons.

I'll check this later, need to align with Spec Part J which has
JVMS 4.9.2
 "Each invokespecial instruction must name ..., or a method in a direct
  superinterface of the current class or interface."

 
> Also the compiled file triggers a verify error. Constant pool entry
> contains MethodRef instead of InterfaceMethodRef. Also should be using
> invokeInterface instead of invokespecial ?

CodeStream.invoke(byte, int, int, char[], char[], char[])
assumes that InterfaceMethodRef is only needed when 
opcode == Opcodes.OPC_invokeinterface 

For super-calls to default methods this assumption is broken: as of 
class file version 52.0 we can use invokespecial with an InterfaceMethodRef.
Thus we need to pass in more information to see whether an InterfaceMethodRef
must be created.
Comment 11 Srikanth Sankaran CLA 2013-11-14 08:50:32 EST
(In reply to Stephan Herrmann from comment #10)

> > _testBug421543b()
> > that shows two problems. Bridge method is getting emitted in X it could be 
> > emitted in J for efficiency reasons.
> 
> I'll check this later, need to align with Spec Part J which has
> JVMS 4.9.2
>  "Each invokespecial instruction must name ..., or a method in a direct
>   superinterface of the current class or interface."

By all means. Please feel free to spawn a follow up, If it is only efficiency
that is a factor it can be taken up later after more pressing work is tended
to.
Comment 12 Stephan Herrmann CLA 2013-11-14 10:12:24 EST
(In reply to Stephan Herrmann from comment #10)
> (In reply to Srikanth Sankaran from comment #4)
> > Also the compiled file triggers a verify error. Constant pool entry
> > contains MethodRef instead of InterfaceMethodRef. Also should be using
> > invokeInterface instead of invokespecial ?
> 
> CodeStream.invoke(byte, int, int, char[], char[], char[])
> assumes that InterfaceMethodRef is only needed when 
> opcode == Opcodes.OPC_invokeinterface 
> 
> For super-calls to default methods this assumption is broken: as of 
> class file version 52.0 we can use invokespecial with an InterfaceMethodRef.
> Thus we need to pass in more information to see whether an InterfaceMethodRef
> must be created.

Fix for this part has been released for BETA_JAVA8 via http://git.eclipse.org/c/jdt/eclipse.jdt.core.git/commit/?h=BETA_JAVA8&id=a575ae7d7233e0fd45c0767401c5464135620572
Comment 13 Stephan Herrmann CLA 2013-11-14 10:16:59 EST
(In reply to Srikanth Sankaran from comment #11)
> (In reply to Stephan Herrmann from comment #10)
> 
> > > _testBug421543b()
> > > that shows two problems. Bridge method is getting emitted in X it could be 
> > > emitted in J for efficiency reasons.
> > 
> > I'll check this later, need to align with Spec Part J which has
> > JVMS 4.9.2
> >  "Each invokespecial instruction must name ..., or a method in a direct
> >   superinterface of the current class or interface."
> 
> By all means. Please feel free to spawn a follow up, If it is only efficiency
> that is a factor it can be taken up later after more pressing work is tended
> to.

-> bug 421747.
Comment 14 Stephan Herrmann CLA 2013-11-19 10:41:59 EST
(In reply to Stephan Herrmann from comment #8)
> (In reply to Stephan Herrmann from comment #7)
> > Experiments indicate that fixing this may introduce a secondary error
> > in InterfaceMethodsTest.testBridge01:
> 
> Probably a red herring. Properly applying the patch from bug 410325
> seems to be all we need for the problem in comment 0.

Yep, after applying the patch from bug 410325 an BETA_JAVA8 the new testBug421543a() runs green. Enabled via http://git.eclipse.org/c/jdt/eclipse.jdt.core.git/commit/?h=BETA_JAVA8&id=4106ed4f2c445aec08a08761ce48c9289a12d1a9

So with one part fixed from bug 410325, a verify error fixed as of comment 12 and some more postponed to bug 421747 all should be taken care of.
Comment 15 Srikanth Sankaran CLA 2013-11-19 13:32:14 EST
(In reply to Stephan Herrmann from comment #14)

> Yep, after applying the patch from bug 410325 an BETA_JAVA8 the new
> testBug421543a() runs green. Enabled via

This breaks the builds. With the new uninterned type comparison error :)
Fixed here: http://git.eclipse.org/c/jdt/eclipse.jdt.core.git/commit/?h=BETA_JAVA8&id=af0e25a1d5ee864ea84d164d70f77532a60cf58e

Please upgrade to 4.3.1 + BETA_JAVA8 updates for development :)
Comment 16 Stephan Herrmann CLA 2013-11-19 14:01:14 EST
(In reply to Srikanth Sankaran from comment #15)
> Please upgrade to 4.3.1 + BETA_JAVA8 updates for development :)

Sorry, I have everything installed, simply launched the wrong installation :(

Should probably start deleting some of my 20 Eclipse installations...