public inbox for gcc-prs@sourceware.org help / color / mirror / Atom feed
From: osk@hem.passagen.se To: java-gnats@sourceware.cygnus.com Subject: java/1320: inner class $finit$ compilation error Date: Wed, 20 Dec 2000 12:24:00 -0000 [thread overview] Message-ID: <20000804120631.30049.qmail@sourceware.cygnus.com> (raw) >Number: 1320 >Category: java >Synopsis: inner class $finit$ compilation error >Confidential: no >Severity: serious >Priority: medium >Responsible: apbianco >State: open >Class: sw-bug >Submitter-Id: net >Arrival-Date: Wed Dec 20 12:19:02 PST 2000 >Closed-Date: >Last-Modified: Tue Oct 31 18:50:01 PST 2000 >Originator: Oskar Liljeblad >Release: unknown-1.0 >Organization: >Environment: egcs 2.96 20000731 >Description: Compile the two files below like this: $ gcj -C AbstractList.java LinkedList.java LinkedList.java: In class `LinkedList$Entry': LinkedList.java: In method `<init>(LinkedList)': LinkedList.java:8: Can't find method `$finit$()' in type `LinkedList$Entry'. Candidates are: `$finit$()' in `LinkedList$Entry' `$finit$()' in `AbstractList'. } ^ 1 error $ This is a weird error because any of the following things fixes the error: * Compile using "gcj -C LinkedList.java AbstractList.java" instead. * Remove the '= 0' initalization in AbstractList. * Remove the '= null' initialization in LinkedList.Entry. >How-To-Repeat: Put this in LinkedList.java: class LinkedList extends AbstractList { class Entry { Object data = null; } } Put this in AbstractList.java: abstract class AbstractList { int modCount = 0; } >Fix: >Release-Note: >Audit-Trail: Formerly PR gcj/298 From: Bryce McKinlay <bryce@albatross.co.nz> To: java-gnats@sourceware.cygnus.com, apbianco@cygnus.com, osk@hem.passagen.se Cc: Subject: Re: gcj/298 Date: Fri, 20 Oct 2000 12:44:09 +1300 > $ gcj -C AbstractList.java LinkedList.java > LinkedList.java: In class `LinkedList$Entry': > LinkedList.java: In method `<init>(LinkedList)': > LinkedList.java:8: Can't find method `$finit$()' in type `LinkedList$Entry'. Candidates are: > `$finit$()' in `LinkedList$Entry' > `$finit$()' in `AbstractList'. > } > I think this one is a variant on PR 285. With the 285 fix applied it doesn't happen. regards [ bryce ] http://sources.redhat.com/cgi-bin/gnatsweb.pl?cmd=view&pr=298&database=java State-Changed-From-To: open->closed State-Changed-By: apbianco State-Changed-When: Thu Oct 19 21:05:46 2000 State-Changed-Why: As Bryce pointed out, this is a duplicate. I checked in a patch: http://gcc.gnu.org/ml/gcc-patches/2000-10/msg00646.html From: Alexandre Petit-Bianco <apbianco@cygnus.com> To: java-gnats@sourceware.cygnus.com Cc: Subject: Re: gcj/298 Date: Thu, 19 Oct 2000 21:03:41 -0700 (PDT) Bryce McKinlay writes: > I think this one is a variant on PR 285. With the 285 fix applied it > doesn't happen. Yes. I checked in your patch and I'm closing this PR: http://gcc.gnu.org/ml/gcc-patches/2000-10/msg00646.html ./A From: apbianco@cygnus.com To: apbianco@cygnus.com, java-gnats@sourceware.cygnus.com, osk@hem.passagen.se Cc: Subject: Re: gcj/298 Date: 20 Oct 2000 04:05:46 -0000 Synopsis: inner class $finit$ compilation error State-Changed-From-To: open->closed State-Changed-By: apbianco State-Changed-When: Thu Oct 19 21:05:46 2000 State-Changed-Why: As Bryce pointed out, this is a duplicate. I checked in a patch: http://gcc.gnu.org/ml/gcc-patches/2000-10/msg00646.html http://sources.redhat.com/cgi-bin/gnatsweb.pl?cmd=view&pr=298&database=java State-Changed-From-To: closed->open State-Changed-By: bryce State-Changed-When: Tue Oct 31 03:10:27 2000 State-Changed-Why: Oops. It isn't fixed ;-( From: Bryce McKinlay <bryce@albatross.co.nz> To: java-gnats@sourceware.cygnus.com, apbianco@cygnus.com, osk@hem.passagen.se Cc: Subject: Re: gcj/298 Date: Wed, 01 Nov 2000 00:10:51 +1300 I initially couldn't reproduce this bug, and thought it was a duplicate of PR 285. But its back (and manifests itself in the classpath collections classes, as the original test case would suggest) The reason I missed it last time is because the problem apparantly depends on the order in which the classes are parsed. In the following example, "Base" must be either be decalred before PR298 or be in a different source file for the problem to occur. class Base { int a = 0; } public class PR298 extends Base { class Entry { int z = 0; } } $ gcj -c PR298.java PR298.java: In class `PR298$Entry': PR298.java: In method `<init>(PR298)': PR298.java:12: Can't find method `finit$()' in type `PR298$Entry'. Candidates are: `finit$()' in `PR298$Entry' `finit$()' in `Base'. } ^ 1 error And yes, I definatly have the PR285 fix installed! I'm reopening this PR. http://sources.redhat.com/cgi-bin/gnatsweb.pl?cmd=view&pr=298&database=java From: bryce@albatross.co.nz To: apbianco@cygnus.com, java-gnats@sourceware.cygnus.com, osk@hem.passagen.se Cc: Subject: Re: gcj/298 Date: 31 Oct 2000 11:10:28 -0000 Synopsis: inner class $finit$ compilation error State-Changed-From-To: closed->open State-Changed-By: bryce State-Changed-When: Tue Oct 31 03:10:27 2000 State-Changed-Why: Oops. It isn't fixed ;-( http://sources.redhat.com/cgi-bin/gnatsweb.pl?cmd=view&pr=298&database=java From: Alexandre Petit-Bianco <apbianco@cygnus.com> To: bryce@albatross.co.nz Cc: java-gnats@sourceware.cygnus.com Subject: Re: gcj/298 Date: Tue, 31 Oct 2000 16:19:13 -0800 (PST) bryce@albatross.co.nz writes: > Oops. It isn't fixed ;-( Yes, it isn't fixed. I came up with a better example, all in one file: class List { void foo () {} } class LinkedList extends List { class Entry { void x () { foo (); } public void foo () {} } } This is an interesting case. A first search produces two candidates: List.foo and LinkedList$Entry.foo. In the search for the most specific method, we find that their arguments are compatibles. So with the candidate we should retain, we try: valid_method_invocation_conversion_p (List, LinkedList$Entry) Which makes us call valid_ref_assignconv_cast_p (LinkedList$Entry, List, 0) And we find that we can't assign LinkedList$Entry to List so we propagate false as a return value in the call chain and we don't mark our candidate (LinkedList$Entry.foo) to be more specific than what we've seen so far. Eventually we fail at finding one and we bail. Jikes and Javac found that LinkedList$Entry.foo is more specific than List.foo. I don't know what criterion they used. ./A From: Tom Tromey <tromey@cygnus.com> To: Alexandre Petit-Bianco <apbianco@cygnus.com> Cc: java-gnats@sourceware.cygnus.com Subject: Re: gcj/298 Date: 31 Oct 2000 17:48:25 -0700 Alex> class List { Alex> void foo () {} Alex> } Alex> class LinkedList extends List { Alex> class Entry { Alex> void x () { foo (); } Alex> public void foo () {} Alex> } Alex> } Alex> Jikes and Javac found that LinkedList$Entry.foo is more Alex> specific than List.foo. I don't know what criterion they used. To me it makes sense that an inner class' method is more specific than one from the outer context. I think `this.foo()' is more specific than `this$0.foo'. I looked here: http://java.sun.com/docs/books/jls/html/1.1Update.html and I saw this sentence: When resolving identifiers, the inner class's enclosing object (also called its enclosing instance) is searched for fields and methods after the class's own this. This implies the rule that Jikes follows. Am I missing something? Tom From: Alexandre Petit-Bianco <apbianco@cygnus.com> To: java-gnats@sourceware.cygnus.com Cc: Subject: Re: gcj/298 Date: Tue, 31 Oct 2000 16:57:22 -0800 (PST) Tom Tromey writes: > To me it makes sense that an inner class' method is more specific > than one from the outer context. I think `this.foo()' is more > specific than `this$0.foo'. Yes, but there are rules in the JLS to express that. Once you checked the candidate's argument(s), if you can use the method invocation conversion rule on the type of the declaration context of one candidate over the other one(s), then the method become more specific and might be eventually retained. > and I saw this sentence: > > When resolving identifiers, the inner class's enclosing object (also > called its enclosing instance) is searched for fields and methods > after the class's own this. > > This implies the rule that Jikes follows. > > Am I missing something? No -- that explains why its correct to have two candidates in our case. But this isn't the logic that is used to tell whether a candidate method is more specific than the rest of the selected crowd. ./A From: Bryce McKinlay <bryce@albatross.co.nz> To: apbianco@redhat.com Cc: java-gnats@sourceware.cygnus.com Subject: Re: gcj/298 Date: Wed, 01 Nov 2000 14:47:05 +1300 Alexandre Petit-Bianco wrote: > This is an interesting case. A first search produces two candidates: > List.foo and LinkedList$Entry.foo. In the search for the most specific > method, we find that their arguments are compatibles. So with the > candidate we should retain, we try: > > valid_method_invocation_conversion_p (List, LinkedList$Entry) > > Which makes us call > > valid_ref_assignconv_cast_p (LinkedList$Entry, List, 0) > > And we find that we can't assign LinkedList$Entry to List so we > propagate false as a return value in the call chain and we don't mark > our candidate (LinkedList$Entry.foo) to be more specific than what > we've seen so far. Eventually we fail at finding one and we bail. > > Jikes and Javac found that LinkedList$Entry.foo is more specific than > List.foo. I don't know what criterion they used. Simple - the method in the innermost context is always the most specific! May I refer you to PR 322, which is somewhat related to this. Method resolution should always stop at the first nesting level in which a matching method name (not signature) is found. eg: if I change the example to class List { void foo (int i) {} <--- } class LinkedList extends List { class Entry { void x () { foo (1); } <--- public void foo () {} } } then it should not compile, because only Entry.foo() is ever considered by the compiler, and its signature does not match. When a method's signature matches exactly a method declared in an outer context, the innermost definition is always used, unless the call is explicitly qualified with "Outerclass.this". However, outer contexts still need to be checked, because in the case where an intermediate context inherits a method that hides a method in an outer context, javac throws an error. eg: class A { void a(int i) { } } class O { void a(int i, int k) {} class B extends A { class C { void b() { a(1); } } } } $ javac Patch.java Patch.java:16: a(int) is inherited from A and hides method in outer class O. An explicit 'this' qualifier must be used to select the desired instance. a(1); ^ 1 error Note that it does this even though the signatures of the two a() methods do not match. regards [ bryce ] From: Alexandre Petit-Bianco <apbianco@cygnus.com> To: Bryce McKinlay <bryce@albatross.co.nz> Cc: java-gnats@sourceware.cygnus.com Subject: Re: gcj/298 Date: Tue, 31 Oct 2000 18:07:50 -0800 (PST) Bryce McKinlay writes: > When a method's signature matches exactly a method declared in an > outer context, the innermost definition is always used, unless the > call is explicitly qualified with "Outerclass.this". OK. > However, outer contexts still need to be checked, because in the > case where an intermediate context inherits a method that hides a > method in an outer context, javac throws an error. eg: OK. This makes sense -- do you happen to know where in the LRM all this is specified. ./A From: Bryce McKinlay <bryce@albatross.co.nz> To: apbianco@redhat.com Cc: java-gnats@sourceware.cygnus.com Subject: Re: gcj/298 Date: Wed, 01 Nov 2000 15:49:13 +1300 Alexandre Petit-Bianco wrote: > This makes sense -- do you happen to know where in the LRM all this is > specified. Nope. AFAIK, call resolution from inner classes isn't really specified anywhere. There are even various subtle differences in the way jikes and javac behave (javac seems more inclined to make guesses, while jikes is more likely to ask you for explicit qualification). I think the paragraph from the "1.1 update" page that Tom posted is about as good as it gets, it all depends on how you interpret it. regards [ bryce ] >Unformatted:
reply other threads:[~2000-12-20 12:24 UTC|newest] Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20000804120631.30049.qmail@sourceware.cygnus.com \ --to=osk@hem.passagen.se \ --cc=java-gnats@sourceware.cygnus.com \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).