Bug 314556 - [1.5][compiler] compiler fails to report attempt to assign weaker access privileges
Summary: [1.5][compiler] compiler fails to report attempt to assign weaker access priv...
Status: VERIFIED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.6   Edit
Hardware: PC Windows 7
: P3 normal (vote)
Target Milestone: 3.7 M1   Edit
Assignee: Srikanth Sankaran CLA
QA Contact:
URL:
Whiteboard:
Keywords:
: 363724 (view as bug list)
Depends on:
Blocks:
 
Reported: 2010-05-26 15:20 EDT by Nick Radov CLA
Modified: 2011-11-14 13:29 EST (History)
2 users (show)

See Also:
Olivier_Thomann: review+


Attachments
Patch under consideration. (6.39 KB, patch)
2010-07-07 06:52 EDT, Srikanth Sankaran CLA
no flags Details | Diff
Revised patch (6.41 KB, patch)
2010-07-07 10:46 EDT, Srikanth Sankaran CLA
no flags Details | Diff
Cleaner patch (5.16 KB, patch)
2010-07-09 01:01 EDT, Srikanth Sankaran CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Nick Radov CLA 2010-05-26 15:20:58 EDT
Build Identifier: 20100218-1602

The Java compiler is failing to report an error on a generic type that attempts to assign weaker access privileges to a member method. At first I thought that the Eclipse compiler was working correctly and there was a bug in the Oracle JDK compiler, however after I submitted Bug ID 6946211 to Oracle they determined that their compiler is working correctly and the bug is in Eclipse. For the reason why please see the JLS, section 4.9 <http://java.sun.com/docs/books/jls/third_edition/html/typesValues.html#4.9>: "Then the intersection type has the same members as a class type with an empty body, direct superclass Ck, and direct superinterfaces IT1... ".

Reproducible: Always

Steps to Reproduce:
Create files for the following sample code and compile them.

public interface BaseType {
   BaseType clone() throws CloneNotSupportedException;
}

public interface SubType<T extends BaseType & java.io.Closeable> extends BaseType {
}

That code compiles with no errors in Eclipse. However, the Oracle JDK 1.6.0_20 javac compiler correctly reports this error.

SubType.java:1: clone() in java.lang.Object cannot implement clone() in BaseType; attempting to assign weaker access privileges; was public
public interface SubType<T extends BaseType & java.io.Closeable> extends BaseType {
                        ^
1 error
Comment 1 Olivier Thomann CLA 2010-05-26 15:23:04 EDT
A candidate for 3.6.1
Comment 2 Srikanth Sankaran CLA 2010-06-02 08:36:48 EDT
(In reply to comment #0)
> Build Identifier: 20100218-1602
> 
> The Java compiler is failing to report an error on a generic type that attempts
> to assign weaker access privileges to a member method. At first I thought that
> the Eclipse compiler was working correctly and there was a bug in the Oracle
> JDK compiler, however after I submitted Bug ID 6946211 to Oracle they
> determined that their compiler is working correctly and the bug is in Eclipse.

Do you have the correct bug number ? 6946211 appears to be an invalid
bug -- Thanks.
Comment 3 Nick Radov CLA 2010-06-02 10:39:05 EDT
(In reply to comment #2)
> Do you have the correct bug number ? 6946211 appears to be an invalid
> bug -- Thanks.

Bug number 6946211 is correct for what I reported to Oracle but for some reason it still isn't publicly visible. According to Jonathan Gibbons it is visible in Oracle's internal bug database.
http://mail.openjdk.java.net/pipermail/compiler-dev/2010-May/002008.html
If you need further information you can check with him on the compiler-dev@openjdk.java.net mailing list.
Comment 4 Srikanth Sankaran CLA 2010-07-02 03:07:54 EDT
Don't see method verification happening on intersection
types anywhere.
Comment 5 Srikanth Sankaran CLA 2010-07-07 06:52:30 EDT
Created attachment 173634 [details]
Patch under consideration.
Comment 6 Srikanth Sankaran CLA 2010-07-07 06:57:19 EDT
(In reply to comment #3)
> (In reply to comment #2)
> > Do you have the correct bug number ? 6946211 appears to be an invalid
> > bug -- Thanks.
> 
> Bug number 6946211 is correct for what I reported to Oracle but for some reason
> it still isn't publicly visible. 

It still isn't, but you are right, this is an eclipse bug.

(In reply to comment #4)
> Don't see method verification happening on intersection
> types anywhere.

That was misspoken, org.eclipse.jdt.internal.compiler.lookup.MethodVerifier15.checkTypeVariableMethods(TypeParameter) handles the relevant verification.
Comment 7 Srikanth Sankaran CLA 2010-07-07 10:46:07 EDT
Created attachment 173659 [details]
Revised patch

Same as earlier patch, but this one removes some gratuitous
whitespace added by earlier one that causes some tests to
fail.

All tests pass with this patch.
Comment 8 Srikanth Sankaran CLA 2010-07-07 10:47:17 EDT
Olivier, please review. Let me know if you want it
for 3.6.1, Thanks in advance.
Comment 9 Nick Radov CLA 2010-07-07 12:55:31 EDT
(In reply to comment #7)
> Created an attachment (id=173659) [details]
> Revised patch

I think there might be a typo in your patch.

+409 = Cannot reduce the visibility of the inherited method{0} from {1}

Should there be a space in front on "{0}"?
Comment 10 Srikanth Sankaran CLA 2010-07-08 00:19:16 EDT
(In reply to comment #9)
> (In reply to comment #7)
> > Created an attachment (id=173659) [details] [details]
> > Revised patch
> 
> I think there might be a typo in your patch.
> 
> +409 = Cannot reduce the visibility of the inherited method{0} from {1}
> 
> Should there be a space in front on "{0}"?

Thanks for looking through the patch :)

No, there isn't a typo here. The string has been deliberately massaged
that way to avoid having to introduce another problem code with its own
message text.

409 gets issued in cases like:

class A {
    public void foo() {}
};

class B extends A {
    void foo() {}
}

with a message of the form:

"Cannot reduce the visibility of the inherited method from A"

Notice that the method name is missing here, but the user is not
handicapped since the IDE (or the command line compiler) underlines
the offending the method name.

In the new scenario where this error gets issued however, the
message will be useless unless the method name is mentioned. 
It doesn't pay to just say:
"Cannot reduce the visibility of the inherited method from BaseType",
we also want to mention the method name as in:
"Cannot reduce the visibility of the inherited method clone() from BaseType"

Always mentioning the method name will work, but will result in gazillion
existing tests "failing" and so will need remastering of all existing tests
that elicit this message, which I was trying to avoid.

In general, I would view such changes as hacks, but in this case the
concerned message gets emitted in all of 1 place (other than the new
one), so it was deemed ok.
Comment 11 Srikanth Sankaran CLA 2010-07-09 01:01:52 EDT
Created attachment 173837 [details]
Cleaner patch
Comment 12 Srikanth Sankaran CLA 2010-07-09 01:07:38 EDT
(1) The latest patch eliminates the need for the white space hack
discussed in comment#10

(2) Uses org.eclipse.jdt.core.compiler.IProblem.InheritedMethodReducesVisibility
to report the problem instead of org.eclipse.jdt.core.compiler.IProblem.MethodReducesVisibility.
This actually results in better message:

"The inherited method Object.clone() cannot hide the public abstract method in BaseType" 

c.f. earlier one:

"Cannot reduce the visibility of the inherited method clone() from BaseType"

(3) Is consistent with the message we would produce for case below:

interface I {
    public void foo();
}

class B {
    void foo() {}
}

class C extends B implements I {
}
Comment 13 Srikanth Sankaran CLA 2010-07-13 00:06:15 EDT
Released in HEAD for 3.7 M1.

Will release in 3.6 maintenance stream if it is deemed suitable
after code review is done.
Comment 14 Olivier Thomann CLA 2010-07-21 11:29:24 EDT
Looks good.
Not sure we need to backport this one. How frequent is this code pattern?
Comment 15 Srikanth Sankaran CLA 2010-07-22 00:35:17 EDT
(In reply to comment #14)
> Looks good.
> Not sure we need to backport this one. How frequent is this code pattern?

Well, we have never performed this verification earlier and have
gotten by, so I would say it is not very common. Also this is a case
of our compiling something which we should not as opposed to the other
way around, so I'll bypass back porting this.

FWIW, the Sun/Oracle bug which was not visible externally earlier is
visible now: (http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6946211)
The "However rejecting the program seems a bit harsh" comment notwithstanding,
there is no question that javac behavior was correct and eclipse's incorrect
until this fix harmonized them.

So in summary, I suggest we leave it out of 3.6.1
Comment 16 Olivier Thomann CLA 2010-08-04 15:56:20 EDT
Verified for 3.7M1.
Ok to leave it out 3.6.1.
Comment 17 Ayushman Jain CLA 2011-11-14 13:29:24 EST
*** Bug 363724 has been marked as a duplicate of this bug. ***