gc: correctly handle fields of pointer type to recursive forward references
Previously, whether declaring a type which copied the structure of a type it was referenced in via a pointer field would work depended on whether you declared it before or after the type it copied, e.g. type T2 T1; type T1 struct { F *T2 } would work, however type T1 struct { F *T2 }; type T2 T1 wouldn't.
Fixes issue 667.
Ack, we've got a problem when dealing with struct fields, delaying the
walkdef() prevents us from being able to complete the field
generation, e.g.
if(n->type == T) {
*t0 = T;
return t0;
}
kills us when the type isn't set.
Still, this patch covers most cases; I've had to get pretty contrived
to get this to be a problem, e.g.:-
type Foo struct {
F3 *Blah
F1 *Bar
F2 *Boo
}
type Bar Baz
type Baz Blah
type Blah Boo
type Boo Argh
type Argh Foo
I will keep on working to fix this also.
On 1 April 2011 00:36, <lstoakes@gmail.com> wrote:
> Hello golang-dev@googlegroups.com (cc: golang-dev@googlegroups.com),
>
> Please take another look.
>
>
> http://codereview.appspot.com/4313064/
>
--
Lorenzo Stoakes
http://www.codegrunt.co.uk
Ok, so a closer look reveals this is actually a problem with the patch
in general - the struct is not getting typechecked correctly at all,
as the following demonstrates:-
package main
type Foo struct {
Next *Bar
}
type Bar Foo
func main() {
_ = &Foo{&Bar{}}
}
error: 'too many values in struct initializer'
But rearranging the code so type Bar Foo comes first fixes this.
Let me fix this...!
On 1 April 2011 01:56, Lorenzo Stoakes <lstoakes@gmail.com> wrote:
> Ack, we've got a problem when dealing with struct fields, delaying the
> walkdef() prevents us from being able to complete the field
> generation, e.g.
>
> if(n->type == T) {
> *t0 = T;
> return t0;
> }
>
> kills us when the type isn't set.
>
> Still, this patch covers most cases; I've had to get pretty contrived
> to get this to be a problem, e.g.:-
>
> type Foo struct {
> F3 *Blah
> F1 *Bar
> F2 *Boo
> }
>
> type Bar Baz
> type Baz Blah
> type Blah Boo
> type Boo Argh
> type Argh Foo
>
> I will keep on working to fix this also.
>
> On 1 April 2011 00:36, <lstoakes@gmail.com> wrote:
>> Hello golang-dev@googlegroups.com (cc: golang-dev@googlegroups.com),
>>
>> Please take another look.
>>
>>
>> http://codereview.appspot.com/4313064/
>>
>
>
>
> --
> Lorenzo Stoakes
> http://www.codegrunt.co.uk
>
--
Lorenzo Stoakes
http://www.codegrunt.co.uk
Ok - I have now fixed the previous issues. Before I was deferring the
walkdef() until after all top-level types had been constructed,
however that just leads to problems because things rely on the
typechecking having actually been done by that point, in particular
stotype(). Instead, I 'defer' copying type information for fields of
pointer type pointing to a type which has a TFORW type somewhere in
its ntype tree until after all top-level types have been constructed.
In fact, we are not technically deferring this, but rather letting
these types stay at TFORW, until they are eventually corrected
afterwards.
I have also updated the fixedbug .go file to something which actually
checks properly whether you can construct the resultant types, as well
as covering every edge-case type I came across. Everything looks good,
and the patch is working and fixes issue 667.
If I'm not clear please forgive me, 2am here in the UK and been a
manic rush to get this one fixed properly :)
Cheers,
Lorenzo
On 3 April 2011 02:06, <lstoakes@gmail.com> wrote:
> Hello golang-dev@googlegroups.com (cc: golang-dev@googlegroups.com),
>
> Please take another look.
>
>
> http://codereview.appspot.com/4313064/
>
--
Lorenzo Stoakes
http://www.codegrunt.co.uk
I am out of country for a couple more days, so will be a slight delay
before getting these done :)
On Thursday, 7 April 2011, <rsc@golang.org> wrote:
>>http://codereview.appspot.com/4313064/diff/12001/src/cmd/gc/typecheck.c#newcode145
> src/cmd/gc/typecheck.c:145: if(isind && n->op == OTYPE && (ft =
> walkforwtype(n->ntype)))
> s/isind/(top&Eindir)/
>
>
I thought the same; however this doesn't work when you nest anonymous
strict declarations in a type, as by the time the typechecker has got
to this point the Eindir has disappeared. I could however modify the
CL to 'remember' the Eindir and pass it through, I didn't do this
previously as I worried it could imply the struct was declared as a
pointer type.
Am happy to attempt this and re-submit to show you what I mean once I
have access to a computer again in a couple of days :)
I agree with all the other comments and will fix then also.
--
Lorenzo Stoakes
http://www.codegrunt.co.uk
Strict = struct. Using phone with autocorrect...
On Thursday, 7 April 2011, Lorenzo Stoakes <lstoakes@gmail.com> wrote:
> I am out of country for a couple more days, so will be a slight delay
> before getting these done :)
>
> On Thursday, 7 April 2011, <rsc@golang.org> wrote:
>
>>>http://codereview.appspot.com/4313064/diff/12001/src/cmd/gc/typecheck.c#newcode145
>> src/cmd/gc/typecheck.c:145: if(isind && n->op == OTYPE && (ft =
>> walkforwtype(n->ntype)))
>> s/isind/(top&Eindir)/
>>
>>
>
> I thought the same; however this doesn't work when you nest anonymous
> strict declarations in a type, as by the time the typechecker has got
> to this point the Eindir has disappeared. I could however modify the
> CL to 'remember' the Eindir and pass it through, I didn't do this
> previously as I worried it could imply the struct was declared as a
> pointer type.
>
> Am happy to attempt this and re-submit to show you what I mean once I
> have access to a computer again in a couple of days :)
>
> I agree with all the other comments and will fix then also.
>
> --
> Lorenzo Stoakes
> http://www.codegrunt.co.uk
>
--
Lorenzo Stoakes
http://www.codegrunt.co.uk
All fixed up.
We are now sometimes passing around the current 'top' value in
typecheck(), amending it as we go, and sometimes simply making nested
calls to typecheck with a brand new top argument which seems quite
inconsistent. However, if you do start going down the road of making
sure any nested call to typecheck() contains all previous top bit
flags regressions occur, also doing so seems really rather out of the
scope of this CL.
I think it's fine to go ahead with this approach for now, and perhaps
fix the inconsistency in a separate CL. All tests pass under this CL,
incidentally.
On 11 April 2011 12:37, <lstoakes@gmail.com> wrote:
> Hello rsc (cc: golang-dev@googlegroups.com),
>
> Please take another look.
>
>
> http://codereview.appspot.com/4313064/
>
--
Lorenzo Stoakes
http://www.codegrunt.co.uk
Let me know if there is anything else you need on this; note that I
also added cycle detection to the getforwtype() function to avoid
infinite loops if, somehow, n->ntype cycles.
On 11 April 2011 12:44, Lorenzo Stoakes <lstoakes@gmail.com> wrote:
> All fixed up.
>
> We are now sometimes passing around the current 'top' value in
> typecheck(), amending it as we go, and sometimes simply making nested
> calls to typecheck with a brand new top argument which seems quite
> inconsistent. However, if you do start going down the road of making
> sure any nested call to typecheck() contains all previous top bit
> flags regressions occur, also doing so seems really rather out of the
> scope of this CL.
>
> I think it's fine to go ahead with this approach for now, and perhaps
> fix the inconsistency in a separate CL. All tests pass under this CL,
> incidentally.
>
> On 11 April 2011 12:37, <lstoakes@gmail.com> wrote:
>> Hello rsc (cc: golang-dev@googlegroups.com),
>>
>> Please take another look.
>>
>>
>> http://codereview.appspot.com/4313064/
>>
>
>
>
> --
> Lorenzo Stoakes
> http://www.codegrunt.co.uk
>
--
Lorenzo Stoakes
http://www.codegrunt.co.uk
Hi, Wondered whether there was any update on this patch? I don't mean to be ...
12 years, 12 months ago
(2011-04-25 15:09:29 UTC)
#16
Hi,
Wondered whether there was any update on this patch? I don't mean to
be impatient, and forgive me if it is simply a matter of other, higher
priority tasks taking precedence, but just wanted to know where we
were with it. I am happy to make any changes necessary to get it in
:-)
Lorenzo
On 19 April 2011 18:13, <lstoakes@gmail.com> wrote:
> Hello rsc (cc: golang-dev@googlegroups.com),
>
> Please take another look.
>
>
> http://codereview.appspot.com/4313064/
>
--
Lorenzo Stoakes
http://www.codegrunt.co.uk
On 25 April 2011 16:43, Russ Cox <rsc@golang.org> wrote: > it's on a long but ...
12 years, 12 months ago
(2011-04-25 16:10:25 UTC)
#18
On 25 April 2011 16:43, Russ Cox <rsc@golang.org> wrote:
> it's on a long but shrinking list
>
Ok, cool, thanks, apologies for sounding a little impatient, but just
wanted to make sure it was still alive :-)
Cheers, Lorenzo
--
Lorenzo Stoakes
http://www.codegrunt.co.uk
On 26 April 2011 17:11, Lorenzo Stoakes <lstoakes@gmail.com> wrote: > See above note. However, there ...
12 years, 12 months ago
(2011-04-26 16:12:30 UTC)
#24
On 26 April 2011 17:11, Lorenzo Stoakes <lstoakes@gmail.com> wrote:
> See above note.
However, there might be a nicer way of doing this without threading
'top' through everything. I am happy to investigate further.
--
Lorenzo Stoakes
http://www.codegrunt.co.uk
On 26 April 2011 17:12, Lorenzo Stoakes <lstoakes@gmail.com> wrote: > However, there might be a ...
12 years, 12 months ago
(2011-04-26 16:24:47 UTC)
#25
On 26 April 2011 17:12, Lorenzo Stoakes <lstoakes@gmail.com> wrote:
> However, there might be a nicer way of doing this without threading
> 'top' through everything. I am happy to investigate further.
Aha! I can simply have the cycle detector return T rather than fire a
fatal error should a cycle be detected.
I am removing the threading as we speak... :)
--
Lorenzo Stoakes
http://www.codegrunt.co.uk
*** Submitted as http://code.google.com/p/go/source/detail?r=3c73bb78da9a *** gc: correctly handle fields of pointer type to recursive forward ...
12 years, 12 months ago
(2011-04-28 04:13:52 UTC)
#28
*** Submitted as http://code.google.com/p/go/source/detail?r=3c73bb78da9a ***
gc: correctly handle fields of pointer type to recursive forward references
Previously, whether declaring a type which copied the structure of a type it was
referenced in via a pointer field would work depended on whether you declared it
before or after the type it copied, e.g. type T2 T1; type T1 struct { F *T2 }
would work, however type T1 struct { F *T2 }; type T2 T1 wouldn't.
Fixes issue 667.
R=rsc
CC=golang-dev
http://codereview.appspot.com/4313064
Committer: Russ Cox <rsc@golang.org>
Issue 4313064: code review 4313064: gc: correctly handle fields of pointer type to recursiv...
(Closed)
Created 13 years ago by lstoakes
Modified 12 years, 12 months ago
Reviewers:
Base URL:
Comments: 9