diff options
Diffstat (limited to 'src/cmd/gc')
35 files changed, 6715 insertions, 3758 deletions
diff --git a/src/cmd/gc/align.c b/src/cmd/gc/align.c index 6982bbe56..be9f552f6 100644 --- a/src/cmd/gc/align.c +++ b/src/cmd/gc/align.c @@ -15,8 +15,8 @@ static int defercalc; -uint32 -rnd(uint32 o, uint32 r) +vlong +rnd(vlong o, vlong r) { if(r < 1 || r > 8 || (r&(r-1)) != 0) fatal("rnd"); @@ -54,6 +54,11 @@ widstruct(Type *errtype, Type *t, vlong o, int flag) for(f=t->type; f!=T; f=f->down) { if(f->etype != TFIELD) fatal("widstruct: not TFIELD: %lT", f); + if(f->type == T) { + // broken field, just skip it so that other valid fields + // get a width. + continue; + } dowidth(f->type); if(f->type->align > maxalign) maxalign = f->type->align; @@ -248,8 +253,12 @@ dowidth(Type *t) checkwidth(t->type); t->align = widthptr; } - else if(t->bound == -100) - yyerror("use of [...] array outside of array literal"); + else if(t->bound == -100) { + if(!t->broke) { + yyerror("use of [...] array outside of array literal"); + t->broke = 1; + } + } else fatal("dowidth %T", t); // probably [...]T break; @@ -607,7 +616,7 @@ typeinit(void) fatal("typeinit: %s already defined", s->name); t = typ(etype); - t->sym = s; + t->sym = s1; dowidth(t); types[etype] = t; @@ -615,12 +624,12 @@ typeinit(void) } Array_array = rnd(0, widthptr); - Array_nel = rnd(Array_array+widthptr, types[TUINT32]->width); - Array_cap = rnd(Array_nel+types[TUINT32]->width, types[TUINT32]->width); - sizeof_Array = rnd(Array_cap+types[TUINT32]->width, widthptr); + Array_nel = rnd(Array_array+widthptr, widthint); + Array_cap = rnd(Array_nel+widthint, widthint); + sizeof_Array = rnd(Array_cap+widthint, widthptr); // string is same as slice wo the cap - sizeof_String = rnd(Array_nel+types[TUINT32]->width, widthptr); + sizeof_String = rnd(Array_nel+widthint, widthptr); dowidth(types[TSTRING]); dowidth(idealstring); diff --git a/src/cmd/gc/bisonerrors b/src/cmd/gc/bisonerrors index 0f865d086..8886a8e52 100755 --- a/src/cmd/gc/bisonerrors +++ b/src/cmd/gc/bisonerrors @@ -41,9 +41,9 @@ grammar && NF>0 { } # In state dumps, record shift/reduce actions. -bison && /^state 0/ { grammar = 0; states = 1 } +bison && /^[Ss]tate 0/ { grammar = 0; states = 1 } -states && /^state / { state = $2 } +states && /^[Ss]tate / { state = $2 } states { statetext[state] = statetext[state] $0 "\n" } states && / shift/ { diff --git a/src/cmd/gc/builtin.c b/src/cmd/gc/builtin.c index ca3d6670d..7de448d1e 100644 --- a/src/cmd/gc/builtin.c +++ b/src/cmd/gc/builtin.c @@ -1,118 +1,119 @@ char *runtimeimport = "package runtime\n" "import runtime \"runtime\"\n" - "func @\"\".new(@\"\".typ *byte) (? *any)\n" - "func @\"\".panicindex()\n" - "func @\"\".panicslice()\n" - "func @\"\".throwreturn()\n" - "func @\"\".throwinit()\n" - "func @\"\".panicwrap(? string, ? string, ? string)\n" - "func @\"\".panic(? interface {})\n" - "func @\"\".recover(? *int32) (? interface {})\n" - "func @\"\".printbool(? bool)\n" - "func @\"\".printfloat(? float64)\n" - "func @\"\".printint(? int64)\n" - "func @\"\".printuint(? uint64)\n" - "func @\"\".printcomplex(? complex128)\n" - "func @\"\".printstring(? string)\n" - "func @\"\".printpointer(? any)\n" - "func @\"\".printiface(? any)\n" - "func @\"\".printeface(? any)\n" - "func @\"\".printslice(? any)\n" - "func @\"\".printnl()\n" - "func @\"\".printsp()\n" - "func @\"\".goprintf()\n" - "func @\"\".concatstring()\n" - "func @\"\".append()\n" - "func @\"\".appendslice(@\"\".typ *byte, @\"\".x any, @\"\".y []any) (? any)\n" - "func @\"\".appendstr(@\"\".typ *byte, @\"\".x []byte, @\"\".y string) (? []byte)\n" - "func @\"\".cmpstring(? string, ? string) (? int)\n" - "func @\"\".slicestring(? string, ? int, ? int) (? string)\n" - "func @\"\".slicestring1(? string, ? int) (? string)\n" - "func @\"\".intstring(? int64) (? string)\n" - "func @\"\".slicebytetostring(? []byte) (? string)\n" - "func @\"\".slicerunetostring(? []rune) (? string)\n" - "func @\"\".stringtoslicebyte(? string) (? []byte)\n" - "func @\"\".stringtoslicerune(? string) (? []rune)\n" - "func @\"\".stringiter(? string, ? int) (? int)\n" - "func @\"\".stringiter2(? string, ? int) (@\"\".retk int, @\"\".retv rune)\n" - "func @\"\".copy(@\"\".to any, @\"\".fr any, @\"\".wid uint32) (? int)\n" - "func @\"\".slicestringcopy(@\"\".to any, @\"\".fr any) (? int)\n" - "func @\"\".convI2E(@\"\".elem any) (@\"\".ret any)\n" - "func @\"\".convI2I(@\"\".typ *byte, @\"\".elem any) (@\"\".ret any)\n" - "func @\"\".convT2E(@\"\".typ *byte, @\"\".elem any) (@\"\".ret any)\n" - "func @\"\".convT2I(@\"\".typ *byte, @\"\".typ2 *byte, @\"\".elem any) (@\"\".ret any)\n" - "func @\"\".assertE2E(@\"\".typ *byte, @\"\".iface any) (@\"\".ret any)\n" - "func @\"\".assertE2E2(@\"\".typ *byte, @\"\".iface any) (@\"\".ret any, @\"\".ok bool)\n" - "func @\"\".assertE2I(@\"\".typ *byte, @\"\".iface any) (@\"\".ret any)\n" - "func @\"\".assertE2I2(@\"\".typ *byte, @\"\".iface any) (@\"\".ret any, @\"\".ok bool)\n" - "func @\"\".assertE2T(@\"\".typ *byte, @\"\".iface any) (@\"\".ret any)\n" - "func @\"\".assertE2T2(@\"\".typ *byte, @\"\".iface any) (@\"\".ret any, @\"\".ok bool)\n" - "func @\"\".assertI2E(@\"\".typ *byte, @\"\".iface any) (@\"\".ret any)\n" - "func @\"\".assertI2E2(@\"\".typ *byte, @\"\".iface any) (@\"\".ret any, @\"\".ok bool)\n" - "func @\"\".assertI2I(@\"\".typ *byte, @\"\".iface any) (@\"\".ret any)\n" - "func @\"\".assertI2I2(@\"\".typ *byte, @\"\".iface any) (@\"\".ret any, @\"\".ok bool)\n" - "func @\"\".assertI2T(@\"\".typ *byte, @\"\".iface any) (@\"\".ret any)\n" - "func @\"\".assertI2T2(@\"\".typ *byte, @\"\".iface any) (@\"\".ret any, @\"\".ok bool)\n" - "func @\"\".ifaceeq(@\"\".i1 any, @\"\".i2 any) (@\"\".ret bool)\n" - "func @\"\".efaceeq(@\"\".i1 any, @\"\".i2 any) (@\"\".ret bool)\n" - "func @\"\".ifacethash(@\"\".i1 any) (@\"\".ret uint32)\n" - "func @\"\".efacethash(@\"\".i1 any) (@\"\".ret uint32)\n" - "func @\"\".equal(@\"\".typ *byte, @\"\".x1 any, @\"\".x2 any) (@\"\".ret bool)\n" - "func @\"\".makemap(@\"\".mapType *byte, @\"\".hint int64) (@\"\".hmap map[any]any)\n" - "func @\"\".mapaccess1(@\"\".mapType *byte, @\"\".hmap map[any]any, @\"\".key any) (@\"\".val any)\n" - "func @\"\".mapaccess2(@\"\".mapType *byte, @\"\".hmap map[any]any, @\"\".key any) (@\"\".val any, @\"\".pres bool)\n" - "func @\"\".mapassign1(@\"\".mapType *byte, @\"\".hmap map[any]any, @\"\".key any, @\"\".val any)\n" - "func @\"\".mapassign2(@\"\".mapType *byte, @\"\".hmap map[any]any, @\"\".key any, @\"\".val any, @\"\".pres bool)\n" - "func @\"\".mapiterinit(@\"\".mapType *byte, @\"\".hmap map[any]any, @\"\".hiter *any)\n" - "func @\"\".mapdelete(@\"\".mapType *byte, @\"\".hmap map[any]any, @\"\".key any)\n" - "func @\"\".mapiternext(@\"\".hiter *any)\n" - "func @\"\".mapiter1(@\"\".hiter *any) (@\"\".key any)\n" - "func @\"\".mapiter2(@\"\".hiter *any) (@\"\".key any, @\"\".val any)\n" - "func @\"\".makechan(@\"\".chanType *byte, @\"\".hint int64) (@\"\".hchan chan any)\n" - "func @\"\".chanrecv1(@\"\".chanType *byte, @\"\".hchan <-chan any) (@\"\".elem any)\n" - "func @\"\".chanrecv2(@\"\".chanType *byte, @\"\".hchan <-chan any) (@\"\".elem any, @\"\".received bool)\n" - "func @\"\".chansend1(@\"\".chanType *byte, @\"\".hchan chan<- any, @\"\".elem any)\n" - "func @\"\".closechan(@\"\".hchan any)\n" - "func @\"\".selectnbsend(@\"\".chanType *byte, @\"\".hchan chan<- any, @\"\".elem any) (? bool)\n" - "func @\"\".selectnbrecv(@\"\".chanType *byte, @\"\".elem *any, @\"\".hchan <-chan any) (? bool)\n" - "func @\"\".selectnbrecv2(@\"\".chanType *byte, @\"\".elem *any, @\"\".received *bool, @\"\".hchan <-chan any) (? bool)\n" - "func @\"\".newselect(@\"\".size int) (@\"\".sel *byte)\n" - "func @\"\".selectsend(@\"\".sel *byte, @\"\".hchan chan<- any, @\"\".elem *any) (@\"\".selected bool)\n" - "func @\"\".selectrecv(@\"\".sel *byte, @\"\".hchan <-chan any, @\"\".elem *any) (@\"\".selected bool)\n" - "func @\"\".selectrecv2(@\"\".sel *byte, @\"\".hchan <-chan any, @\"\".elem *any, @\"\".received *bool) (@\"\".selected bool)\n" - "func @\"\".selectdefault(@\"\".sel *byte) (@\"\".selected bool)\n" - "func @\"\".selectgo(@\"\".sel *byte)\n" - "func @\"\".block()\n" - "func @\"\".makeslice(@\"\".typ *byte, @\"\".nel int64, @\"\".cap int64) (@\"\".ary []any)\n" - "func @\"\".growslice(@\"\".typ *byte, @\"\".old []any, @\"\".n int64) (@\"\".ary []any)\n" - "func @\"\".sliceslice1(@\"\".old []any, @\"\".lb uint64, @\"\".width uint64) (@\"\".ary []any)\n" - "func @\"\".sliceslice(@\"\".old []any, @\"\".lb uint64, @\"\".hb uint64, @\"\".width uint64) (@\"\".ary []any)\n" - "func @\"\".slicearray(@\"\".old *any, @\"\".nel uint64, @\"\".lb uint64, @\"\".hb uint64, @\"\".width uint64) (@\"\".ary []any)\n" - "func @\"\".closure()\n" - "func @\"\".memequal(@\"\".eq *bool, @\"\".size uintptr, @\"\".x *any, @\"\".y *any)\n" - "func @\"\".memequal8(@\"\".eq *bool, @\"\".size uintptr, @\"\".x *any, @\"\".y *any)\n" - "func @\"\".memequal16(@\"\".eq *bool, @\"\".size uintptr, @\"\".x *any, @\"\".y *any)\n" - "func @\"\".memequal32(@\"\".eq *bool, @\"\".size uintptr, @\"\".x *any, @\"\".y *any)\n" - "func @\"\".memequal64(@\"\".eq *bool, @\"\".size uintptr, @\"\".x *any, @\"\".y *any)\n" - "func @\"\".memequal128(@\"\".eq *bool, @\"\".size uintptr, @\"\".x *any, @\"\".y *any)\n" - "func @\"\".int64div(? int64, ? int64) (? int64)\n" - "func @\"\".uint64div(? uint64, ? uint64) (? uint64)\n" - "func @\"\".int64mod(? int64, ? int64) (? int64)\n" - "func @\"\".uint64mod(? uint64, ? uint64) (? uint64)\n" - "func @\"\".float64toint64(? float64) (? int64)\n" - "func @\"\".float64touint64(? float64) (? uint64)\n" - "func @\"\".int64tofloat64(? int64) (? float64)\n" - "func @\"\".uint64tofloat64(? uint64) (? float64)\n" - "func @\"\".complex128div(@\"\".num complex128, @\"\".den complex128) (@\"\".quo complex128)\n" + "func @\"\".new (@\"\".typ·2 *byte) (? *any)\n" + "func @\"\".panicindex ()\n" + "func @\"\".panicslice ()\n" + "func @\"\".throwreturn ()\n" + "func @\"\".throwinit ()\n" + "func @\"\".panicwrap (? string, ? string, ? string)\n" + "func @\"\".panic (? interface {})\n" + "func @\"\".recover (? *int32) (? interface {})\n" + "func @\"\".printbool (? bool)\n" + "func @\"\".printfloat (? float64)\n" + "func @\"\".printint (? int64)\n" + "func @\"\".printuint (? uint64)\n" + "func @\"\".printcomplex (? complex128)\n" + "func @\"\".printstring (? string)\n" + "func @\"\".printpointer (? any)\n" + "func @\"\".printiface (? any)\n" + "func @\"\".printeface (? any)\n" + "func @\"\".printslice (? any)\n" + "func @\"\".printnl ()\n" + "func @\"\".printsp ()\n" + "func @\"\".goprintf ()\n" + "func @\"\".concatstring ()\n" + "func @\"\".append ()\n" + "func @\"\".appendslice (@\"\".typ·2 *byte, @\"\".x·3 any, @\"\".y·4 []any) (? any)\n" + "func @\"\".appendstr (@\"\".typ·2 *byte, @\"\".x·3 []byte, @\"\".y·4 string) (? []byte)\n" + "func @\"\".cmpstring (? string, ? string) (? int)\n" + "func @\"\".eqstring (? string, ? string) (? bool)\n" + "func @\"\".intstring (? int64) (? string)\n" + "func @\"\".slicebytetostring (? []byte) (? string)\n" + "func @\"\".slicerunetostring (? []rune) (? string)\n" + "func @\"\".stringtoslicebyte (? string) (? []byte)\n" + "func @\"\".stringtoslicerune (? string) (? []rune)\n" + "func @\"\".stringiter (? string, ? int) (? int)\n" + "func @\"\".stringiter2 (? string, ? int) (@\"\".retk·1 int, @\"\".retv·2 rune)\n" + "func @\"\".copy (@\"\".to·2 any, @\"\".fr·3 any, @\"\".wid·4 uintptr) (? int)\n" + "func @\"\".slicestringcopy (@\"\".to·2 any, @\"\".fr·3 any) (? int)\n" + "func @\"\".typ2Itab (@\"\".typ·2 *byte, @\"\".typ2·3 *byte, @\"\".cache·4 **byte) (@\"\".ret·1 *byte)\n" + "func @\"\".convI2E (@\"\".elem·2 any) (@\"\".ret·1 any)\n" + "func @\"\".convI2I (@\"\".typ·2 *byte, @\"\".elem·3 any) (@\"\".ret·1 any)\n" + "func @\"\".convT2E (@\"\".typ·2 *byte, @\"\".elem·3 any) (@\"\".ret·1 any)\n" + "func @\"\".convT2I (@\"\".typ·2 *byte, @\"\".typ2·3 *byte, @\"\".cache·4 **byte, @\"\".elem·5 any) (@\"\".ret·1 any)\n" + "func @\"\".assertE2E (@\"\".typ·2 *byte, @\"\".iface·3 any) (@\"\".ret·1 any)\n" + "func @\"\".assertE2E2 (@\"\".typ·3 *byte, @\"\".iface·4 any) (@\"\".ret·1 any, @\"\".ok·2 bool)\n" + "func @\"\".assertE2I (@\"\".typ·2 *byte, @\"\".iface·3 any) (@\"\".ret·1 any)\n" + "func @\"\".assertE2I2 (@\"\".typ·3 *byte, @\"\".iface·4 any) (@\"\".ret·1 any, @\"\".ok·2 bool)\n" + "func @\"\".assertE2T (@\"\".typ·2 *byte, @\"\".iface·3 any) (@\"\".ret·1 any)\n" + "func @\"\".assertE2T2 (@\"\".typ·3 *byte, @\"\".iface·4 any) (@\"\".ret·1 any, @\"\".ok·2 bool)\n" + "func @\"\".assertI2E (@\"\".typ·2 *byte, @\"\".iface·3 any) (@\"\".ret·1 any)\n" + "func @\"\".assertI2E2 (@\"\".typ·3 *byte, @\"\".iface·4 any) (@\"\".ret·1 any, @\"\".ok·2 bool)\n" + "func @\"\".assertI2I (@\"\".typ·2 *byte, @\"\".iface·3 any) (@\"\".ret·1 any)\n" + "func @\"\".assertI2I2 (@\"\".typ·3 *byte, @\"\".iface·4 any) (@\"\".ret·1 any, @\"\".ok·2 bool)\n" + "func @\"\".assertI2T (@\"\".typ·2 *byte, @\"\".iface·3 any) (@\"\".ret·1 any)\n" + "func @\"\".assertI2T2 (@\"\".typ·3 *byte, @\"\".iface·4 any) (@\"\".ret·1 any, @\"\".ok·2 bool)\n" + "func @\"\".assertI2TOK (@\"\".typ·2 *byte, @\"\".iface·3 any) (@\"\".ok·1 bool)\n" + "func @\"\".assertE2TOK (@\"\".typ·2 *byte, @\"\".iface·3 any) (@\"\".ok·1 bool)\n" + "func @\"\".ifaceeq (@\"\".i1·2 any, @\"\".i2·3 any) (@\"\".ret·1 bool)\n" + "func @\"\".efaceeq (@\"\".i1·2 any, @\"\".i2·3 any) (@\"\".ret·1 bool)\n" + "func @\"\".ifacethash (@\"\".i1·2 any) (@\"\".ret·1 uint32)\n" + "func @\"\".efacethash (@\"\".i1·2 any) (@\"\".ret·1 uint32)\n" + "func @\"\".equal (@\"\".typ·2 *byte, @\"\".x1·3 any, @\"\".x2·4 any) (@\"\".ret·1 bool)\n" + "func @\"\".makemap (@\"\".mapType·2 *byte, @\"\".hint·3 int64) (@\"\".hmap·1 map[any]any)\n" + "func @\"\".mapaccess1 (@\"\".mapType·2 *byte, @\"\".hmap·3 map[any]any, @\"\".key·4 any) (@\"\".val·1 any)\n" + "func @\"\".mapaccess2 (@\"\".mapType·3 *byte, @\"\".hmap·4 map[any]any, @\"\".key·5 any) (@\"\".val·1 any, @\"\".pres·2 bool)\n" + "func @\"\".mapassign1 (@\"\".mapType·1 *byte, @\"\".hmap·2 map[any]any, @\"\".key·3 any, @\"\".val·4 any)\n" + "func @\"\".mapiterinit (@\"\".mapType·1 *byte, @\"\".hmap·2 map[any]any, @\"\".hiter·3 *any)\n" + "func @\"\".mapdelete (@\"\".mapType·1 *byte, @\"\".hmap·2 map[any]any, @\"\".key·3 any)\n" + "func @\"\".mapiternext (@\"\".hiter·1 *any)\n" + "func @\"\".mapiter1 (@\"\".hiter·2 *any) (@\"\".key·1 any)\n" + "func @\"\".mapiter2 (@\"\".hiter·3 *any) (@\"\".key·1 any, @\"\".val·2 any)\n" + "func @\"\".makechan (@\"\".chanType·2 *byte, @\"\".hint·3 int64) (@\"\".hchan·1 chan any)\n" + "func @\"\".chanrecv1 (@\"\".chanType·2 *byte, @\"\".hchan·3 <-chan any) (@\"\".elem·1 any)\n" + "func @\"\".chanrecv2 (@\"\".chanType·3 *byte, @\"\".hchan·4 <-chan any) (@\"\".elem·1 any, @\"\".received·2 bool)\n" + "func @\"\".chansend1 (@\"\".chanType·1 *byte, @\"\".hchan·2 chan<- any, @\"\".elem·3 any)\n" + "func @\"\".closechan (@\"\".hchan·1 any)\n" + "func @\"\".selectnbsend (@\"\".chanType·2 *byte, @\"\".hchan·3 chan<- any, @\"\".elem·4 any) (? bool)\n" + "func @\"\".selectnbrecv (@\"\".chanType·2 *byte, @\"\".elem·3 *any, @\"\".hchan·4 <-chan any) (? bool)\n" + "func @\"\".selectnbrecv2 (@\"\".chanType·2 *byte, @\"\".elem·3 *any, @\"\".received·4 *bool, @\"\".hchan·5 <-chan any) (? bool)\n" + "func @\"\".newselect (@\"\".size·2 int32) (@\"\".sel·1 *byte)\n" + "func @\"\".selectsend (@\"\".sel·2 *byte, @\"\".hchan·3 chan<- any, @\"\".elem·4 *any) (@\"\".selected·1 bool)\n" + "func @\"\".selectrecv (@\"\".sel·2 *byte, @\"\".hchan·3 <-chan any, @\"\".elem·4 *any) (@\"\".selected·1 bool)\n" + "func @\"\".selectrecv2 (@\"\".sel·2 *byte, @\"\".hchan·3 <-chan any, @\"\".elem·4 *any, @\"\".received·5 *bool) (@\"\".selected·1 bool)\n" + "func @\"\".selectdefault (@\"\".sel·2 *byte) (@\"\".selected·1 bool)\n" + "func @\"\".selectgo (@\"\".sel·1 *byte)\n" + "func @\"\".block ()\n" + "func @\"\".makeslice (@\"\".typ·2 *byte, @\"\".nel·3 int64, @\"\".cap·4 int64) (@\"\".ary·1 []any)\n" + "func @\"\".growslice (@\"\".typ·2 *byte, @\"\".old·3 []any, @\"\".n·4 int64) (@\"\".ary·1 []any)\n" + "func @\"\".memequal (@\"\".eq·1 *bool, @\"\".size·2 uintptr, @\"\".x·3 *any, @\"\".y·4 *any)\n" + "func @\"\".memequal8 (@\"\".eq·1 *bool, @\"\".size·2 uintptr, @\"\".x·3 *any, @\"\".y·4 *any)\n" + "func @\"\".memequal16 (@\"\".eq·1 *bool, @\"\".size·2 uintptr, @\"\".x·3 *any, @\"\".y·4 *any)\n" + "func @\"\".memequal32 (@\"\".eq·1 *bool, @\"\".size·2 uintptr, @\"\".x·3 *any, @\"\".y·4 *any)\n" + "func @\"\".memequal64 (@\"\".eq·1 *bool, @\"\".size·2 uintptr, @\"\".x·3 *any, @\"\".y·4 *any)\n" + "func @\"\".memequal128 (@\"\".eq·1 *bool, @\"\".size·2 uintptr, @\"\".x·3 *any, @\"\".y·4 *any)\n" + "func @\"\".int64div (? int64, ? int64) (? int64)\n" + "func @\"\".uint64div (? uint64, ? uint64) (? uint64)\n" + "func @\"\".int64mod (? int64, ? int64) (? int64)\n" + "func @\"\".uint64mod (? uint64, ? uint64) (? uint64)\n" + "func @\"\".float64toint64 (? float64) (? int64)\n" + "func @\"\".float64touint64 (? float64) (? uint64)\n" + "func @\"\".int64tofloat64 (? int64) (? float64)\n" + "func @\"\".uint64tofloat64 (? uint64) (? float64)\n" + "func @\"\".complex128div (@\"\".num·2 complex128, @\"\".den·3 complex128) (@\"\".quo·1 complex128)\n" + "func @\"\".racefuncenter (? uintptr)\n" + "func @\"\".racefuncexit ()\n" + "func @\"\".raceread (? uintptr)\n" + "func @\"\".racewrite (? uintptr)\n" "\n" "$$\n"; char *unsafeimport = "package unsafe\n" "import runtime \"runtime\"\n" "type @\"\".Pointer uintptr\n" - "func @\"\".Offsetof(? any) (? uintptr)\n" - "func @\"\".Sizeof(? any) (? uintptr)\n" - "func @\"\".Alignof(? any) (? uintptr)\n" + "func @\"\".Offsetof (? any) (? uintptr)\n" + "func @\"\".Sizeof (? any) (? uintptr)\n" + "func @\"\".Alignof (? any) (? uintptr)\n" "\n" "$$\n"; diff --git a/src/cmd/gc/closure.c b/src/cmd/gc/closure.c index fa44e40fa..4e029ef83 100644 --- a/src/cmd/gc/closure.c +++ b/src/cmd/gc/closure.c @@ -75,6 +75,8 @@ closurebody(NodeList *body) return func; } +static Node* makeclosure(Node *func, int nowrap); + void typecheckclosure(Node *func, int top) { @@ -85,12 +87,12 @@ typecheckclosure(Node *func, int top) oldfn = curfn; typecheck(&func->ntype, Etype); func->type = func->ntype->type; - if(curfn == nil) { - xtop = list(xtop, func); - return; - } - - if(func->type != T) { + + // Type check the body now, but only if we're inside a function. + // At top level (in a variable initialization: curfn==nil) we're not + // ready to type check code yet; we'll check it later, because the + // underlying closure function we create is added to xtop. + if(curfn && func->type != T) { curfn = func; typechecklist(func->nbody, Etop); curfn = oldfn; @@ -120,26 +122,43 @@ typecheckclosure(Node *func, int top) func->enter = list(func->enter, v->heapaddr); v->heapaddr = N; } + + // Create top-level function + xtop = list(xtop, makeclosure(func, func->cvars==nil || (top&Ecall))); } static Node* -makeclosure(Node *func, NodeList **init, int nowrap) +makeclosure(Node *func, int nowrap) { - Node *xtype, *v, *addr, *xfunc; - NodeList *l; + Node *xtype, *v, *addr, *xfunc, *cv; + NodeList *l, *body; static int closgen; char *p; - - USED(init); + int offset; /* * wrap body in external function - * with extra closure parameters. + * that begins by reading closure parameters. */ xtype = nod(OTFUNC, N, N); + xtype->list = func->list; + xtype->rlist = func->rlist; - // each closure variable has a corresponding - // address parameter. + // create the function + xfunc = nod(ODCLFUNC, N, N); + snprint(namebuf, sizeof namebuf, "func·%.3d", ++closgen); + xfunc->nname = newname(lookup(namebuf)); + xfunc->nname->sym->flags |= SymExported; // disable export + xfunc->nname->ntype = xtype; + xfunc->nname->defn = xfunc; + declare(xfunc->nname, PFUNC); + xfunc->nname->funcdepth = func->funcdepth; + xfunc->funcdepth = func->funcdepth; + + // declare variables holding addresses taken from closure + // and initialize in entry prologue. + body = nil; + offset = widthptr; for(l=func->cvars; l; l=l->next) { v = l->n; if(v->op == 0) @@ -149,38 +168,35 @@ makeclosure(Node *func, NodeList **init, int nowrap) addr->sym = lookup(p); free(p); addr->ntype = nod(OIND, typenod(v->type), N); - addr->class = PPARAM; + addr->class = PAUTO; addr->addable = 1; addr->ullman = 1; - + addr->used = 1; + addr->curfn = xfunc; + xfunc->dcl = list(xfunc->dcl, addr); v->heapaddr = addr; - - xtype->list = list(xtype->list, nod(ODCLFIELD, addr, addr->ntype)); + cv = nod(OCLOSUREVAR, N, N); + cv->type = ptrto(v->type); + cv->xoffset = offset; + body = list(body, nod(OAS, addr, cv)); + offset += widthptr; } + typechecklist(body, Etop); + walkstmtlist(body); + xfunc->enter = body; - // then a dummy arg where the closure's caller pc sits - if (!nowrap) - xtype->list = list(xtype->list, nod(ODCLFIELD, N, typenod(types[TUINTPTR]))); - - // then the function arguments - xtype->list = concat(xtype->list, func->list); - xtype->rlist = concat(xtype->rlist, func->rlist); - - // create the function - xfunc = nod(ODCLFUNC, N, N); - snprint(namebuf, sizeof namebuf, "_func_%.3d", ++closgen); - xfunc->nname = newname(lookup(namebuf)); - xfunc->nname->ntype = xtype; - xfunc->nname->defn = xfunc; - declare(xfunc->nname, PFUNC); - xfunc->nname->funcdepth = func->funcdepth; - xfunc->funcdepth = func->funcdepth; xfunc->nbody = func->nbody; - xfunc->dcl = func->dcl; + xfunc->dcl = concat(func->dcl, xfunc->dcl); if(xfunc->nbody == nil) fatal("empty body - won't generate any code"); typecheck(&xfunc, Etop); - closures = list(closures, xfunc); + + xfunc->closure = func; + func->closure = xfunc; + + func->nbody = nil; + func->list = nil; + func->rlist = nil; return xfunc; } @@ -188,51 +204,55 @@ makeclosure(Node *func, NodeList **init, int nowrap) Node* walkclosure(Node *func, NodeList **init) { + Node *clos, *typ; + NodeList *l; + char buf[20]; int narg; - Node *xtype, *xfunc, *call, *clos; - NodeList *l, *in; - // no closure vars, don't bother wrapping + // If no closure vars, don't bother wrapping. if(func->cvars == nil) - return makeclosure(func, init, 1)->nname; + return func->closure->nname; + + // Create closure in the form of a composite literal. + // supposing the closure captures an int i and a string s + // and has one float64 argument and no results, + // the generated code looks like: + // + // clos = &struct{F uintptr; A0 *int; A1 *string}{func·001, &i, &s} + // + // The use of the struct provides type information to the garbage + // collector so that it can walk the closure. We could use (in this case) + // [3]unsafe.Pointer instead, but that would leave the gc in the dark. + // The information appears in the binary in the form of type descriptors; + // the struct is unnamed so that closures in multiple packages with the + // same struct type can share the descriptor. - /* - * wrap body in external function - * with extra closure parameters. - */ - - // create the function - xfunc = makeclosure(func, init, 0); - xtype = xfunc->nname->ntype; - - // prepare call of sys.closure that turns external func into func literal value. - clos = syslook("closure", 1); - clos->type = T; - clos->ntype = nod(OTFUNC, N, N); - in = list1(nod(ODCLFIELD, N, typenod(types[TINT]))); // siz - in = list(in, nod(ODCLFIELD, N, xtype)); narg = 0; + typ = nod(OTSTRUCT, N, N); + typ->list = list1(nod(ODCLFIELD, newname(lookup("F")), typenod(types[TUINTPTR]))); for(l=func->cvars; l; l=l->next) { if(l->n->op == 0) continue; - narg++; - in = list(in, nod(ODCLFIELD, N, l->n->heapaddr->ntype)); + snprint(buf, sizeof buf, "A%d", narg++); + typ->list = list(typ->list, nod(ODCLFIELD, newname(lookup(buf)), l->n->heapaddr->ntype)); } - clos->ntype->list = in; - clos->ntype->rlist = list1(nod(ODCLFIELD, N, typenod(func->type))); + + clos = nod(OCOMPLIT, N, nod(OIND, typ, N)); + clos->esc = func->esc; + clos->right->implicit = 1; + clos->list = concat(list1(nod(OCFUNC, func->closure->nname, N)), func->enter); + + // Force type conversion from *struct to the func type. + clos = nod(OCONVNOP, clos, N); + clos->type = func->type; + typecheck(&clos, Erv); + // typecheck will insert a PTRLIT node under CONVNOP, + // tag it with escape analysis result. + clos->left->esc = func->esc; + walkexpr(&clos, init); - call = nod(OCALL, clos, N); - if(narg*widthptr > 100) - yyerror("closure needs too many variables; runtime will reject it"); - in = list1(nodintconst(narg*widthptr)); - in = list(in, xfunc->nname); - in = concat(in, func->enter); - call->list = in; - - typecheck(&call, Erv); - walkexpr(&call, init); - return call; + return clos; } // Special case for closures that get called in place. @@ -242,6 +262,7 @@ walkclosure(Node *func, NodeList **init) void walkcallclosure(Node *n, NodeList **init) { + USED(init); if (n->op != OCALLFUNC || n->left->op != OCLOSURE) { dump("walkcallclosure", n); fatal("abuse of walkcallclosure"); @@ -250,7 +271,7 @@ walkcallclosure(Node *n, NodeList **init) // New arg list for n. First the closure-args // and then the original parameter list. n->list = concat(n->left->enter, n->list); - n->left = makeclosure(n->left, init, 1)->nname; + n->left = n->left->closure->nname; dowidth(n->left->type); n->type = getoutargx(n->left->type); // for a single valued function, pull the field type out of the struct diff --git a/src/cmd/gc/const.c b/src/cmd/gc/const.c index e27c88338..4f1ff6778 100644 --- a/src/cmd/gc/const.c +++ b/src/cmd/gc/const.c @@ -87,8 +87,12 @@ convlit1(Node **np, Type *t, int explicit) switch(n->op) { default: - if(n->type == idealbool) - n->type = types[TBOOL]; + if(n->type == idealbool) { + if(t->etype == TBOOL) + n->type = t; + else + n->type = types[TBOOL]; + } if(n->type->etype == TIDEAL) { convlit(&n->left, t); convlit(&n->right, t); @@ -162,6 +166,16 @@ convlit1(Node **np, Type *t, int explicit) case TFUNC: case TUNSAFEPTR: break; + + case TUINTPTR: + // A nil literal may be converted to uintptr + // if it is an unsafe.Pointer + if(n->type->etype == TUNSAFEPTR) { + n->val.u.xval = mal(sizeof(*n->val.u.xval)); + mpmovecfix(n->val.u.xval, 0); + n->val.ctype = CTINT; + } else + goto bad; } break; @@ -230,7 +244,8 @@ convlit1(Node **np, Type *t, int explicit) bad: if(!n->diag) { - yyerror("cannot convert %N to type %T", n, t); + if(!t->broke) + yyerror("cannot convert %N to type %T", n, t); n->diag = 1; } if(isideal(n->type)) { @@ -348,13 +363,9 @@ toint(Val v) return v; } -void -overflow(Val v, Type *t) +int +doesoverflow(Val v, Type *t) { - // v has already been converted - // to appropriate form for t. - if(t == T || t->etype == TIDEAL) - return; switch(v.ctype) { case CTINT: case CTRUNE: @@ -362,14 +373,14 @@ overflow(Val v, Type *t) fatal("overflow: %T integer constant", t); if(mpcmpfixfix(v.u.xval, minintval[t->etype]) < 0 || mpcmpfixfix(v.u.xval, maxintval[t->etype]) > 0) - yyerror("constant %B overflows %T", v.u.xval, t); + return 1; break; case CTFLT: if(!isfloat[t->etype]) fatal("overflow: %T floating-point constant", t); if(mpcmpfltflt(v.u.fval, minfltval[t->etype]) <= 0 || mpcmpfltflt(v.u.fval, maxfltval[t->etype]) >= 0) - yyerror("constant %#F overflows %T", v.u.fval, t); + return 1; break; case CTCPLX: if(!iscomplex[t->etype]) @@ -378,7 +389,33 @@ overflow(Val v, Type *t) mpcmpfltflt(&v.u.cval->real, maxfltval[t->etype]) >= 0 || mpcmpfltflt(&v.u.cval->imag, minfltval[t->etype]) <= 0 || mpcmpfltflt(&v.u.cval->imag, maxfltval[t->etype]) >= 0) - yyerror("constant %#F overflows %T", v.u.fval, t); + return 1; + break; + } + return 0; +} + +void +overflow(Val v, Type *t) +{ + // v has already been converted + // to appropriate form for t. + if(t == T || t->etype == TIDEAL) + return; + + if(!doesoverflow(v, t)) + return; + + switch(v.ctype) { + case CTINT: + case CTRUNE: + yyerror("constant %B overflows %T", v.u.xval, t); + break; + case CTFLT: + yyerror("constant %#F overflows %T", v.u.fval, t); + break; + case CTCPLX: + yyerror("constant %#F overflows %T", v.u.fval, t); break; } } @@ -437,6 +474,20 @@ isconst(Node *n, int ct) return t == ct || (ct == CTINT && t == CTRUNE); } +static Node* +saveorig(Node *n) +{ + Node *n1; + + if(n == n->orig) { + // duplicate node for n->orig. + n1 = nod(OLITERAL, N, N); + n->orig = n1; + *n1 = *n; + } + return n->orig; +} + /* * if n is constant, rewrite as OLITERAL node. */ @@ -902,12 +953,7 @@ unary: } ret: - if(n == n->orig) { - // duplicate node for n->orig. - norig = nod(OLITERAL, N, N); - *norig = *n; - } else - norig = n->orig; + norig = saveorig(n); *n = *nl; // restore value of n->orig. n->orig = norig; @@ -924,11 +970,15 @@ ret: return; settrue: + norig = saveorig(n); *n = *nodbool(1); + n->orig = norig; return; setfalse: + norig = saveorig(n); *n = *nodbool(0); + n->orig = norig; return; } @@ -984,79 +1034,88 @@ nodcplxlit(Val r, Val i) return n; } -// TODO(rsc): combine with convlit +// idealkind returns a constant kind like consttype +// but for an arbitrary "ideal" expression. +static int +idealkind(Node *n) +{ + int k1, k2; + + if(n == N || !isideal(n->type)) + return CTxxx; + + switch(n->op) { + default: + return CTxxx; + case OLITERAL: + return n->val.ctype; + case OADD: + case OAND: + case OANDNOT: + case OCOM: + case ODIV: + case OMINUS: + case OMOD: + case OMUL: + case OSUB: + case OXOR: + case OOR: + case OPLUS: + // numeric kinds. + k1 = idealkind(n->left); + k2 = idealkind(n->right); + if(k1 > k2) + return k1; + else + return k2; + case OADDSTR: + return CTSTR; + case OANDAND: + case OEQ: + case OGE: + case OGT: + case OLE: + case OLT: + case ONE: + case ONOT: + case OOROR: + case OCMPSTR: + case OCMPIFACE: + return CTBOOL; + case OLSH: + case ORSH: + // shifts (beware!). + return idealkind(n->left); + } +} + void defaultlit(Node **np, Type *t) { int lno; + int ctype; Node *n, *nn; + Type *t1; n = *np; if(n == N || !isideal(n->type)) return; - switch(n->op) { - case OLITERAL: + if(n->op == OLITERAL) { nn = nod(OXXX, N, N); *nn = *n; n = nn; *np = n; - break; - case OLSH: - case ORSH: - defaultlit(&n->left, t); - t = n->left->type; - if(t != T && !isint[t->etype]) { - yyerror("invalid operation: %N (shift of type %T)", n, t); - t = T; - } - n->type = t; - return; - case ONOT: - defaultlit(&n->left, t); - n->type = n->left->type; - return; - default: - if(n->left == N) { - dump("defaultlit", n); - fatal("defaultlit"); - } - // n is ideal, so left and right must both be ideal. - // n has not been computed as a constant value, - // so either left or right must not be constant. - // The only 'ideal' non-constant expressions are shifts. Ugh. - // If one of these is a shift and the other is not, use that type. - // When compiling x := 1<<i + 3.14, this means we try to push - // the float64 down into the 1<<i, producing the correct error - // (cannot shift float64). - if(t == T && (n->right->op == OLSH || n->right->op == ORSH)) { - defaultlit(&n->left, T); - defaultlit(&n->right, n->left->type); - } else if(t == T && (n->left->op == OLSH || n->left->op == ORSH)) { - defaultlit(&n->right, T); - defaultlit(&n->left, n->right->type); - } else if(iscmp[n->op]) { - defaultlit2(&n->left, &n->right, 1); - } else { - defaultlit(&n->left, t); - defaultlit(&n->right, t); - } - if(n->type == idealbool || n->type == idealstring) { - if(t != T && t->etype == n->type->etype) - n->type = t; - else - n->type = types[n->type->etype]; - } else - n->type = n->left->type; - return; } lno = setlineno(n); - switch(n->val.ctype) { + ctype = idealkind(n); + t1 = T; + switch(ctype) { default: if(t != T) { convlit(np, t); - break; + return; } if(n->val.ctype == CTNIL) { lineno = lno; @@ -1065,46 +1124,52 @@ defaultlit(Node **np, Type *t) break; } if(n->val.ctype == CTSTR) { - n->type = types[TSTRING]; + t1 = types[TSTRING]; + convlit(np, t1); break; } yyerror("defaultlit: unknown literal: %N", n); break; + case CTxxx: + fatal("defaultlit: idealkind is CTxxx: %+N", n); + break; case CTBOOL: - n->type = types[TBOOL]; + t1 = types[TBOOL]; if(t != T && t->etype == TBOOL) - n->type = t; + t1 = t; + convlit(np, t1); break; case CTINT: - n->type = types[TINT]; + t1 = types[TINT]; goto num; case CTRUNE: - n->type = runetype; + t1 = runetype; goto num; case CTFLT: - n->type = types[TFLOAT64]; + t1 = types[TFLOAT64]; goto num; case CTCPLX: - n->type = types[TCOMPLEX128]; + t1 = types[TCOMPLEX128]; goto num; num: if(t != T) { if(isint[t->etype]) { - n->type = t; + t1 = t; n->val = toint(n->val); } else if(isfloat[t->etype]) { - n->type = t; + t1 = t; n->val = toflt(n->val); } else if(iscomplex[t->etype]) { - n->type = t; + t1 = t; n->val = tocplx(n->val); } } - overflow(n->val, n->type); + overflow(n->val, t1); + convlit(np, t1); break; } lineno = lno; @@ -1206,6 +1271,7 @@ smallintconst(Node *n) case TIDEAL: case TINT64: case TUINT64: + case TPTR64: if(mpcmpfixfix(n->val.u.xval, minintval[TINT32]) < 0 || mpcmpfixfix(n->val.u.xval, maxintval[TINT32]) > 0) break; @@ -1392,3 +1458,132 @@ cmplxdiv(Mpcplx *v, Mpcplx *rv) mpsubfltflt(&v->imag, &ad); // bc-ad mpdivfltflt(&v->imag, &cc_plus_dd); // (bc+ad)/(cc+dd) } + +static int hascallchan(Node*); + +// Is n a Go language constant (as opposed to a compile-time constant)? +// Expressions derived from nil, like string([]byte(nil)), while they +// may be known at compile time, are not Go language constants. +// Only called for expressions known to evaluated to compile-time +// constants. +int +isgoconst(Node *n) +{ + Node *l; + Type *t; + + if(n->orig != N) + n = n->orig; + + switch(n->op) { + case OADD: + case OADDSTR: + case OAND: + case OANDAND: + case OANDNOT: + case OCOM: + case ODIV: + case OEQ: + case OGE: + case OGT: + case OLE: + case OLSH: + case OLT: + case OMINUS: + case OMOD: + case OMUL: + case ONE: + case ONOT: + case OOR: + case OOROR: + case OPLUS: + case ORSH: + case OSUB: + case OXOR: + case OCONV: + case OIOTA: + case OCOMPLEX: + case OREAL: + case OIMAG: + if(isgoconst(n->left) && (n->right == N || isgoconst(n->right))) + return 1; + break; + + case OLEN: + case OCAP: + l = n->left; + if(isgoconst(l)) + return 1; + // Special case: len/cap is constant when applied to array or + // pointer to array when the expression does not contain + // function calls or channel receive operations. + t = l->type; + if(t != T && isptr[t->etype]) + t = t->type; + if(isfixedarray(t) && !hascallchan(l)) + return 1; + break; + + case OLITERAL: + if(n->val.ctype != CTNIL) + return 1; + break; + + case ONAME: + l = n->sym->def; + if(l->op == OLITERAL && n->val.ctype != CTNIL) + return 1; + break; + + case ONONAME: + if(n->sym->def != N && n->sym->def->op == OIOTA) + return 1; + break; + + case OCALL: + // Only constant calls are unsafe.Alignof, Offsetof, and Sizeof. + l = n->left; + while(l->op == OPAREN) + l = l->left; + if(l->op != ONAME || l->sym->pkg != unsafepkg) + break; + if(strcmp(l->sym->name, "Alignof") == 0 || + strcmp(l->sym->name, "Offsetof") == 0 || + strcmp(l->sym->name, "Sizeof") == 0) + return 1; + break; + } + + //dump("nonconst", n); + return 0; +} + +static int +hascallchan(Node *n) +{ + NodeList *l; + + if(n == N) + return 0; + switch(n->op) { + case OCALL: + case OCALLFUNC: + case OCALLMETH: + case OCALLINTER: + case ORECV: + return 1; + } + + if(hascallchan(n->left) || + hascallchan(n->right)) + return 1; + + for(l=n->list; l; l=l->next) + if(hascallchan(l->n)) + return 1; + for(l=n->rlist; l; l=l->next) + if(hascallchan(l->n)) + return 1; + + return 0; +} diff --git a/src/cmd/gc/cplx.c b/src/cmd/gc/cplx.c index dea7bc3bb..e0127fc59 100644 --- a/src/cmd/gc/cplx.c +++ b/src/cmd/gc/cplx.c @@ -271,7 +271,7 @@ complexgen(Node *n, Node *res) } void -complexbool(int op, Node *nl, Node *nr, int true, Prog *to) +complexbool(int op, Node *nl, Node *nr, int true, int likely, Prog *to) { Node tnl, tnr; Node n1, n2, n3, n4; @@ -323,7 +323,7 @@ complexbool(int op, Node *nl, Node *nr, int true, Prog *to) if(op == ONE) true = !true; - bgen(&na, true, to); + bgen(&na, true, likely, to); } void diff --git a/src/cmd/gc/dcl.c b/src/cmd/gc/dcl.c index 32f334b71..aa2489d9a 100644 --- a/src/cmd/gc/dcl.c +++ b/src/cmd/gc/dcl.c @@ -150,16 +150,35 @@ testdclstack(void) void redeclare(Sym *s, char *where) { - if(s->lastlineno == 0) - yyerror("%S redeclared %s\n" - "\tprevious declaration during import", - s, where); - else + Strlit *pkgstr; + int line1, line2; + + if(s->lastlineno == 0) { + pkgstr = s->origpkg ? s->origpkg->path : s->pkg->path; yyerror("%S redeclared %s\n" + "\tprevious declaration during import \"%Z\"", + s, where, pkgstr); + } else { + line1 = parserline(); + line2 = s->lastlineno; + + // When an import and a declaration collide in separate files, + // present the import as the "redeclared", because the declaration + // is visible where the import is, but not vice versa. + // See issue 4510. + if(s->def == N) { + line2 = line1; + line1 = s->lastlineno; + } + + yyerrorl(line1, "%S redeclared %s\n" "\tprevious declaration at %L", - s, where, s->lastlineno); + s, where, line2); + } } +static int vargen; + /* * declare individual names - var, typ, const */ @@ -168,7 +187,10 @@ declare(Node *n, int ctxt) { Sym *s; int gen; - static int typegen, vargen; + static int typegen; + + if(ctxt == PDISCARD) + return; if(isblank(n)) return; @@ -180,6 +202,9 @@ declare(Node *n, int ctxt) if(importpkg == nil && !typecheckok && s->pkg != localpkg) yyerror("cannot declare name %S", s); + if(ctxt == PEXTERN && strcmp(s->name, "init") == 0) + yyerror("cannot declare init - must be func", s); + gen = 0; if(ctxt == PEXTERN) { externdcl = list(externdcl, n); @@ -192,7 +217,7 @@ declare(Node *n, int ctxt) curfn->dcl = list(curfn->dcl, n); if(n->op == OTYPE) gen = ++typegen; - else if(n->op == ONAME) + else if(n->op == ONAME && ctxt == PAUTO && strstr(s->name, "·") == nil) gen = ++vargen; pushdcl(s); n->curfn = curfn; @@ -237,7 +262,7 @@ variter(NodeList *vl, Node *t, NodeList *el) init = nil; doexpr = el != nil; - + if(count(el) == 1 && count(vl) > 1) { e = el->n; as2 = nod(OAS2, N, N); @@ -464,7 +489,7 @@ colasdefn(NodeList *left, Node *defn) if(isblank(n)) continue; if(!colasname(n)) { - yyerror("non-name %N on left side of :=", n); + yyerrorl(defn->lineno, "non-name %N on left side of :=", n); nerr++; continue; } @@ -479,11 +504,11 @@ colasdefn(NodeList *left, Node *defn) l->n = n; } if(nnew == 0 && nerr == 0) - yyerror("no new variables on left side of :="); + yyerrorl(defn->lineno, "no new variables on left side of :="); } Node* -colas(NodeList *left, NodeList *right) +colas(NodeList *left, NodeList *right, int32 lno) { Node *as; @@ -491,6 +516,7 @@ colas(NodeList *left, NodeList *right) as->list = left; as->rlist = right; as->colas = 1; + as->lineno = lno; colasdefn(left, as); // make the tree prettier; not necessary @@ -515,7 +541,7 @@ ifacedcl(Node *n) if(n->op != ODCLFIELD || n->right == N) fatal("ifacedcl"); - dclcontext = PAUTO; + dclcontext = PPARAM; markdcl(); funcdepth++; n->outer = curfn; @@ -526,6 +552,7 @@ ifacedcl(Node *n) // seen the body of a function but since an interface // field declaration does not have a body, we must // call it now to pop the current declaration context. + dclcontext = PAUTO; funcbody(n); } @@ -567,6 +594,11 @@ funcargs(Node *nt) if(nt->op != OTFUNC) fatal("funcargs %O", nt->op); + // re-start the variable generation number + // we want to use small numbers for the return variables, + // so let them have the chunk starting at 1. + vargen = count(nt->rlist); + // declare the receiver and in arguments. // no n->defn because type checking of func header // will not fill in the types until later @@ -578,6 +610,8 @@ funcargs(Node *nt) n->left->op = ONAME; n->left->ntype = n->right; declare(n->left, PPARAM); + if(dclcontext == PAUTO) + n->left->vargen = ++vargen; } } for(l=nt->list; l; l=l->next) { @@ -588,29 +622,44 @@ funcargs(Node *nt) n->left->op = ONAME; n->left->ntype = n->right; declare(n->left, PPARAM); + if(dclcontext == PAUTO) + n->left->vargen = ++vargen; } } // declare the out arguments. - gen = 0; + gen = count(nt->list); + int i = 0; for(l=nt->rlist; l; l=l->next) { n = l->n; + if(n->op != ODCLFIELD) fatal("funcargs out %O", n->op); - if(n->left != N) { - n->left->op = ONAME; - n->left->ntype = n->right; - if(isblank(n->left)) { - // Give it a name so we can assign to it during return. - // preserve the original in ->orig - nn = nod(OXXX, N, N); - *nn = *n->left; - n->left = nn; - snprint(namebuf, sizeof(namebuf), ".anon%d", gen++); - n->left->sym = lookup(namebuf); - } - declare(n->left, PPARAMOUT); + + if(n->left == N) { + // give it a name so escape analysis has nodes to work with + snprint(namebuf, sizeof(namebuf), "~anon%d", gen++); + n->left = newname(lookup(namebuf)); + // TODO: n->left->missing = 1; + } + + n->left->op = ONAME; + + if(isblank(n->left)) { + // Give it a name so we can assign to it during return. + // preserve the original in ->orig + nn = nod(OXXX, N, N); + *nn = *n->left; + n->left = nn; + + snprint(namebuf, sizeof(namebuf), "~anon%d", gen++); + n->left->sym = lookup(namebuf); } + + n->left->ntype = n->right; + declare(n->left, PPARAMOUT); + if(dclcontext == PAUTO) + n->left->vargen = ++i; } } @@ -978,8 +1027,11 @@ embedded(Sym *s) *utfrune(name, CenterDot) = 0; } - if(exportname(name) || s->pkg == builtinpkg) // old behaviour, tests pass, but is it correct? + if(exportname(name)) n = newname(lookup(name)); + else if(s->pkg == builtinpkg && importpkg != nil) + // The name of embedded builtins during imports belongs to importpkg. + n = newname(pkglookup(name, importpkg)); else n = newname(pkglookup(name, s->pkg)); n = nod(ODCLFIELD, n, oldname(s)); @@ -1124,6 +1176,7 @@ functype(Node *this, NodeList *in, NodeList *out) { Type *t; NodeList *rcvr; + Sym *s; t = typ(TFUNC); @@ -1141,7 +1194,12 @@ functype(Node *this, NodeList *in, NodeList *out) t->thistuple = 1; t->outtuple = count(out); t->intuple = count(in); - t->outnamed = t->outtuple > 0 && out->n->left != N; + t->outnamed = 0; + if(t->outtuple > 0 && out->n->left != N && out->n->left->orig != N) { + s = out->n->left->orig->sym; + if(s != S && s->name[0] != '~') + t->outnamed = 1; + } return t; } @@ -1249,7 +1307,7 @@ methodname1(Node *n, Node *t) * n is fieldname, pa is base type, t is function type */ void -addmethod(Sym *sf, Type *t, int local) +addmethod(Sym *sf, Type *t, int local, int nointerface) { Type *f, *d, *pa; Node *n; @@ -1332,6 +1390,7 @@ addmethod(Sym *sf, Type *t, int local) } f = structfield(n); + f->nointerface = nointerface; // during import unexported method names should be in the type's package if(importpkg && f->sym && !exportname(f->sym->name) && f->sym->pkg != structpkg) @@ -1382,3 +1441,20 @@ funccompile(Node *n, int isclosure) funcdepth = 0; dclcontext = PEXTERN; } + +Sym* +funcsym(Sym *s) +{ + char *p; + Sym *s1; + + p = smprint("%s·f", s->name); + s1 = pkglookup(p, s->pkg); + free(p); + if(s1->def == N) { + s1->def = newname(s1); + s1->def->shortname = newname(s); + funcsyms = list(funcsyms, s1->def); + } + return s1; +} diff --git a/src/cmd/gc/doc.go b/src/cmd/gc/doc.go index 8d8f8967b..791967708 100644 --- a/src/cmd/gc/doc.go +++ b/src/cmd/gc/doc.go @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +// +build ignore + /* Gc is the generic label for the family of Go compilers @@ -25,6 +27,8 @@ other packages. It is therefore not necessary when compiling client C of package P to read the files of P's dependencies, only the compiled output of P. +Command Line + Usage: go tool 6g [flags] file... The specified files must be Go source files and all part of the same package. @@ -48,15 +52,40 @@ Flags: disable optimizations -S write assembly language text to standard output (code only) - -SS + -S -S write assembly language text to standard output (code and data) -u disallow importing packages not marked as safe -V print the compiler version + -race + compile with race detection enabled There are also a number of debugging flags; run the command with no arguments to get a usage message. +Compiler Directives + +The compiler accepts two compiler directives in the form of // comments at the +beginning of a line. To distinguish them from non-directive comments, the directives +require no space between the slashes and the name of the directive. However, since +they are comments, tools unaware of the directive convention or of a particular +directive can skip over a directive like any other comment. + + //line path/to/file:linenumber + +The //line directive specifies that the source line that follows should be recorded +as having come from the given file path and line number. Successive lines are +recorded using increasing line numbers, until the next directive. This directive +typically appears in machine-generated code, so that compilers and debuggers +will show lines in the original input to the generator. + + //go:noescape + +The //go:noescape directive specifies that the next declaration in the file, which +must be a func without a body (meaning that it has an implementation not written +in Go) does not allow any of the pointers passed as arguments to escape into the +heap or into the values returned from the function. This information can be used as +during the compiler's escape analysis of Go code calling the function. */ -package documentation +package main diff --git a/src/cmd/gc/esc.c b/src/cmd/gc/esc.c index 8a265ce59..46c06d10e 100644 --- a/src/cmd/gc/esc.c +++ b/src/cmd/gc/esc.c @@ -1,8 +1,162 @@ // Copyright 2011 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// + // Escape analysis. + +#include <u.h> +#include <libc.h> +#include "go.h" + +// Run analysis on minimal sets of mutually recursive functions +// or single non-recursive functions, bottom up. +// +// Finding these sets is finding strongly connected components +// in the static call graph. The algorithm for doing that is taken +// from Sedgewick, Algorithms, Second Edition, p. 482, with two +// adaptations. +// +// First, a hidden closure function (n->curfn != N) cannot be the +// root of a connected component. Refusing to use it as a root +// forces it into the component of the function in which it appears. +// The analysis assumes that closures and the functions in which they +// appear are analyzed together, so that the aliasing between their +// variables can be modeled more precisely. +// +// Second, each function becomes two virtual nodes in the graph, +// with numbers n and n+1. We record the function's node number as n +// but search from node n+1. If the search tells us that the component +// number (min) is n+1, we know that this is a trivial component: one function +// plus its closures. If the search tells us that the component number is +// n, then there was a path from node n+1 back to node n, meaning that +// the function set is mutually recursive. The escape analysis can be +// more precise when analyzing a single non-recursive function than +// when analyzing a set of mutually recursive functions. + +static NodeList *stack; +static uint32 visitgen; +static uint32 visit(Node*); +static uint32 visitcode(Node*, uint32); +static uint32 visitcodelist(NodeList*, uint32); + +static void analyze(NodeList*, int); + +enum +{ + EscFuncUnknown = 0, + EscFuncPlanned, + EscFuncStarted, + EscFuncTagged, +}; + +void +escapes(NodeList *all) +{ + NodeList *l; + + for(l=all; l; l=l->next) + l->n->walkgen = 0; + + visitgen = 0; + for(l=all; l; l=l->next) + if(l->n->op == ODCLFUNC && l->n->curfn == N) + visit(l->n); + + for(l=all; l; l=l->next) + l->n->walkgen = 0; +} + +static uint32 +visit(Node *n) +{ + uint32 min, recursive; + NodeList *l, *block; + + if(n->walkgen > 0) { + // already visited + return n->walkgen; + } + + visitgen++; + n->walkgen = visitgen; + visitgen++; + min = visitgen; + + l = mal(sizeof *l); + l->next = stack; + l->n = n; + stack = l; + min = visitcodelist(n->nbody, min); + if((min == n->walkgen || min == n->walkgen+1) && n->curfn == N) { + // This node is the root of a strongly connected component. + + // The original min passed to visitcodelist was n->walkgen+1. + // If visitcodelist found its way back to n->walkgen, then this + // block is a set of mutually recursive functions. + // Otherwise it's just a lone function that does not recurse. + recursive = min == n->walkgen; + + // Remove connected component from stack. + // Mark walkgen so that future visits return a large number + // so as not to affect the caller's min. + block = stack; + for(l=stack; l->n != n; l=l->next) + l->n->walkgen = (uint32)~0U; + n->walkgen = (uint32)~0U; + stack = l->next; + l->next = nil; + + // Run escape analysis on this set of functions. + analyze(block, recursive); + } + + return min; +} + +static uint32 +visitcodelist(NodeList *l, uint32 min) +{ + for(; l; l=l->next) + min = visitcode(l->n, min); + return min; +} + +static uint32 +visitcode(Node *n, uint32 min) +{ + Node *fn; + uint32 m; + + if(n == N) + return min; + + min = visitcodelist(n->ninit, min); + min = visitcode(n->left, min); + min = visitcode(n->right, min); + min = visitcodelist(n->list, min); + min = visitcode(n->ntest, min); + min = visitcode(n->nincr, min); + min = visitcodelist(n->nbody, min); + min = visitcodelist(n->nelse, min); + min = visitcodelist(n->rlist, min); + + if(n->op == OCALLFUNC || n->op == OCALLMETH) { + fn = n->left; + if(n->op == OCALLMETH) + fn = n->left->right->sym->def; + if(fn && fn->op == ONAME && fn->class == PFUNC && fn->defn && fn->defn->nbody) + if((m = visit(fn->defn)) < min) + min = m; + } + + if(n->op == OCLOSURE) + if((m = visit(n->closure)) < min) + min = m; + + return min; +} + +// An escape analysis pass for a set of functions. // // First escfunc, esc and escassign recurse over the ast of each // function to dig out flow(dst,src) edges between any @@ -22,75 +176,123 @@ // not escape, then new(T) can be rewritten into a stack allocation. // The same is true of slice literals. // -// If escape analysis is disabled (-s), this code is not used. +// If optimizations are disabled (-N), this code is not used. // Instead, the compiler assumes that any value whose address // is taken without being immediately dereferenced // needs to be moved to the heap, and new(T) and slice // literals are always real allocations. -#include <u.h> -#include <libc.h> -#include "go.h" +typedef struct EscState EscState; + +static void escfunc(EscState*, Node *func); +static void esclist(EscState*, NodeList *l); +static void esc(EscState*, Node *n); +static void escloopdepthlist(EscState*, NodeList *l); +static void escloopdepth(EscState*, Node *n); +static void escassign(EscState*, Node *dst, Node *src); +static void esccall(EscState*, Node*); +static void escflows(EscState*, Node *dst, Node *src); +static void escflood(EscState*, Node *dst); +static void escwalk(EscState*, int level, Node *dst, Node *src); +static void esctag(EscState*, Node *func); + +struct EscState { + // Fake node that all + // - return values and output variables + // - parameters on imported functions not marked 'safe' + // - assignments to global variables + // flow to. + Node theSink; + + NodeList* dsts; // all dst nodes + int loopdepth; // for detecting nested loop scopes + int pdepth; // for debug printing in recursions. + int dstcount, edgecount; // diagnostic + NodeList* noesc; // list of possible non-escaping nodes, for printing + int recursive; // recursive function or group of mutually recursive functions. +}; + +static Strlit *tags[16]; + +static Strlit* +mktag(int mask) +{ + Strlit *s; + char buf[40]; + + switch(mask&EscMask) { + case EscNone: + case EscReturn: + break; + default: + fatal("escape mktag"); + } -static void escfunc(Node *func); -static void esclist(NodeList *l); -static void esc(Node *n); -static void escloopdepthlist(NodeList *l); -static void escloopdepth(Node *n); -static void escassign(Node *dst, Node *src); -static void esccall(Node*); -static void escflows(Node *dst, Node *src); -static void escflood(Node *dst); -static void escwalk(int level, Node *dst, Node *src); -static void esctag(Node *func); - -// Fake node that all -// - return values and output variables -// - parameters on imported functions not marked 'safe' -// - assignments to global variables -// flow to. -static Node theSink; - -static NodeList* dsts; // all dst nodes -static int loopdepth; // for detecting nested loop scopes -static int pdepth; // for debug printing in recursions. -static Strlit* safetag; // gets slapped on safe parameters' field types for export -static int dstcount, edgecount; // diagnostic -static NodeList* noesc; // list of possible non-escaping nodes, for printing + mask >>= EscBits; -void -escapes(NodeList *all) + if(mask < nelem(tags) && tags[mask] != nil) + return tags[mask]; + + snprint(buf, sizeof buf, "esc:0x%x", mask); + s = strlit(buf); + if(mask < nelem(tags)) + tags[mask] = s; + return s; +} + +static int +parsetag(Strlit *note) { - NodeList *l; + int em; + + if(note == nil) + return EscUnknown; + if(strncmp(note->s, "esc:", 4) != 0) + return EscUnknown; + em = atoi(note->s + 4); + if (em == 0) + return EscNone; + return EscReturn | (em << EscBits); +} - theSink.op = ONAME; - theSink.orig = &theSink; - theSink.class = PEXTERN; - theSink.sym = lookup(".sink"); - theSink.escloopdepth = -1; +static void +analyze(NodeList *all, int recursive) +{ + NodeList *l; + EscState es, *e; + + memset(&es, 0, sizeof es); + e = &es; + e->theSink.op = ONAME; + e->theSink.orig = &e->theSink; + e->theSink.class = PEXTERN; + e->theSink.sym = lookup(".sink"); + e->theSink.escloopdepth = -1; + e->recursive = recursive; - safetag = strlit("noescape"); - noesc = nil; + for(l=all; l; l=l->next) + if(l->n->op == ODCLFUNC) + l->n->esc = EscFuncPlanned; // flow-analyze functions for(l=all; l; l=l->next) - if(l->n->op == ODCLFUNC || l->n->op == OCLOSURE) - escfunc(l->n); + if(l->n->op == ODCLFUNC) + escfunc(e, l->n); - // print("escapes: %d dsts, %d edges\n", dstcount, edgecount); + // print("escapes: %d e->dsts, %d edges\n", e->dstcount, e->edgecount); - // visit the updstream of each dst, mark address nodes with + // visit the upstream of each dst, mark address nodes with // addrescapes, mark parameters unsafe - for(l = dsts; l; l=l->next) - escflood(l->n); + for(l = e->dsts; l; l=l->next) + escflood(e, l->n); // for all top level functions, tag the typenodes corresponding to the param nodes for(l=all; l; l=l->next) if(l->n->op == ODCLFUNC) - esctag(l->n); + esctag(e, l->n); if(debug['m']) { - for(l=noesc; l; l=l->next) + for(l=e->noesc; l; l=l->next) if(l->n->esc == EscNone) warnl(l->n->lineno, "%S %hN does not escape", (l->n->curfn && l->n->curfn->nname) ? l->n->curfn->nname->sym : S, @@ -100,14 +302,20 @@ escapes(NodeList *all) static void -escfunc(Node *func) +escfunc(EscState *e, Node *func) { - Node *savefn, *n; + Node *savefn; NodeList *ll; int saveld; - saveld = loopdepth; - loopdepth = 1; +// print("escfunc %N %s\n", func->nname, e->recursive?"(recursive)":""); + + if(func->esc != 1) + fatal("repeat escfunc %N", func->nname); + func->esc = EscFuncStarted; + + saveld = e->loopdepth; + e->loopdepth = 1; savefn = curfn; curfn = func; @@ -116,63 +324,54 @@ escfunc(Node *func) continue; switch (ll->n->class) { case PPARAMOUT: - // output parameters flow to the sink - escflows(&theSink, ll->n); - ll->n->escloopdepth = loopdepth; + // out params are in a loopdepth between the sink and all local variables + ll->n->escloopdepth = 0; break; case PPARAM: if(ll->n->type && !haspointers(ll->n->type)) break; - ll->n->esc = EscNone; // prime for escflood later - noesc = list(noesc, ll->n); - ll->n->escloopdepth = loopdepth; + if(curfn->nbody == nil && !curfn->noescape) + ll->n->esc = EscHeap; + else + ll->n->esc = EscNone; // prime for escflood later + e->noesc = list(e->noesc, ll->n); + ll->n->escloopdepth = 1; break; } } - // walk will take the address of cvar->closure later and assign it to cvar. - // linking a fake oaddr node directly to the closure handles the case - // of the closure itself leaking. Following the flow of the value to th - // paramref is done in escflow, because if we did that here, it would look - // like the original is assigned out of its loop depth, whereas it's just - // assigned to something in an inner function. A paramref itself is never - // moved to the heap, only its original. - for(ll=curfn->cvars; ll; ll=ll->next) { - if(ll->n->op == OXXX) // see dcl.c:398 - continue; - - n = nod(OADDR, ll->n->closure, N); - n->lineno = ll->n->lineno; - typecheck(&n, Erv); - escassign(curfn, n); - } + // in a mutually recursive group we lose track of the return values + if(e->recursive) + for(ll=curfn->dcl; ll; ll=ll->next) + if(ll->n->op == ONAME && ll->n->class == PPARAMOUT) + escflows(e, &e->theSink, ll->n); - escloopdepthlist(curfn->nbody); - esclist(curfn->nbody); + escloopdepthlist(e, curfn->nbody); + esclist(e, curfn->nbody); curfn = savefn; - loopdepth = saveld; + e->loopdepth = saveld; } -// Mark labels that have no backjumps to them as not increasing loopdepth. +// Mark labels that have no backjumps to them as not increasing e->loopdepth. // Walk hasn't generated (goto|label)->left->sym->label yet, so we'll cheat // and set it to one of the following two. Then in esc we'll clear it again. static Label looping; static Label nonlooping; static void -escloopdepthlist(NodeList *l) +escloopdepthlist(EscState *e, NodeList *l) { for(; l; l=l->next) - escloopdepth(l->n); + escloopdepth(e, l->n); } static void -escloopdepth(Node *n) +escloopdepth(EscState *e, Node *n) { if(n == N) return; - escloopdepthlist(n->ninit); + escloopdepthlist(e, n->ninit); switch(n->op) { case OLABEL: @@ -194,29 +393,30 @@ escloopdepth(Node *n) break; } - escloopdepth(n->left); - escloopdepth(n->right); - escloopdepthlist(n->list); - escloopdepth(n->ntest); - escloopdepth(n->nincr); - escloopdepthlist(n->nbody); - escloopdepthlist(n->nelse); - escloopdepthlist(n->rlist); + escloopdepth(e, n->left); + escloopdepth(e, n->right); + escloopdepthlist(e, n->list); + escloopdepth(e, n->ntest); + escloopdepth(e, n->nincr); + escloopdepthlist(e, n->nbody); + escloopdepthlist(e, n->nelse); + escloopdepthlist(e, n->rlist); } static void -esclist(NodeList *l) +esclist(EscState *e, NodeList *l) { for(; l; l=l->next) - esc(l->n); + esc(e, l->n); } static void -esc(Node *n) +esc(EscState *e, Node *n) { int lno; NodeList *ll, *lr; + Node *a; if(n == N) return; @@ -224,33 +424,30 @@ esc(Node *n) lno = setlineno(n); if(n->op == OFOR || n->op == ORANGE) - loopdepth++; - - if(n->op == OCLOSURE) { - escfunc(n); - } else { - esc(n->left); - esc(n->right); - esc(n->ntest); - esc(n->nincr); - esclist(n->ninit); - esclist(n->nbody); - esclist(n->nelse); - esclist(n->list); - esclist(n->rlist); - } + e->loopdepth++; + + esc(e, n->left); + esc(e, n->right); + esc(e, n->ntest); + esc(e, n->nincr); + esclist(e, n->ninit); + esclist(e, n->nbody); + esclist(e, n->nelse); + esclist(e, n->list); + esclist(e, n->rlist); + if(n->op == OFOR || n->op == ORANGE) - loopdepth--; + e->loopdepth--; if(debug['m'] > 1) - print("%L:[%d] %S esc: %N\n", lineno, loopdepth, + print("%L:[%d] %S esc: %N\n", lineno, e->loopdepth, (curfn && curfn->nname) ? curfn->nname->sym : S, n); switch(n->op) { case ODCL: // Record loop depth at declaration. if(n->left) - n->left->escloopdepth = loopdepth; + n->left->escloopdepth = e->loopdepth; break; case OLABEL: @@ -260,18 +457,19 @@ esc(Node *n) } else if(n->left->sym->label == &looping) { if(debug['m'] > 1) print("%L: %N looping label\n", lineno, n); - loopdepth++; + e->loopdepth++; } // See case OLABEL in escloopdepth above // else if(n->left->sym->label == nil) - // fatal("escape anaylysis missed or messed up a label: %+N", n); + // fatal("escape analysis missed or messed up a label: %+N", n); n->left->sym->label = nil; + break; case ORANGE: // Everything but fixed array is a dereference. if(isfixedarray(n->type) && n->list->next) - escassign(n->list->next->n, n->right); + escassign(e, n->list->next->n, n->right); break; case OSWITCH: @@ -279,123 +477,157 @@ esc(Node *n) for(ll=n->list; ll; ll=ll->next) { // cases // ntest->right is the argument of the .(type), // ll->n->nname is the variable per case - escassign(ll->n->nname, n->ntest->right); + escassign(e, ll->n->nname, n->ntest->right); } } break; case OAS: case OASOP: - escassign(n->left, n->right); + escassign(e, n->left, n->right); break; case OAS2: // x,y = a,b if(count(n->list) == count(n->rlist)) for(ll=n->list, lr=n->rlist; ll; ll=ll->next, lr=lr->next) - escassign(ll->n, lr->n); + escassign(e, ll->n, lr->n); break; case OAS2RECV: // v, ok = <-ch case OAS2MAPR: // v, ok = m[k] case OAS2DOTTYPE: // v, ok = x.(type) - escassign(n->list->n, n->rlist->n); + escassign(e, n->list->n, n->rlist->n); break; case OSEND: // ch <- x - escassign(&theSink, n->right); + escassign(e, &e->theSink, n->right); break; case ODEFER: - if(loopdepth == 1) // top level + if(e->loopdepth == 1) // top level break; // arguments leak out of scope // TODO: leak to a dummy node instead // fallthrough case OPROC: // go f(x) - f and x escape - escassign(&theSink, n->left->left); - escassign(&theSink, n->left->right); // ODDDARG for call + escassign(e, &e->theSink, n->left->left); + escassign(e, &e->theSink, n->left->right); // ODDDARG for call for(ll=n->left->list; ll; ll=ll->next) - escassign(&theSink, ll->n); + escassign(e, &e->theSink, ll->n); + break; + + case OCALLMETH: + case OCALLFUNC: + case OCALLINTER: + esccall(e, n); + break; + + case OAS2FUNC: // x,y = f() + // esccall already done on n->rlist->n. tie it's escretval to n->list + lr=n->rlist->n->escretval; + for(ll=n->list; lr && ll; lr=lr->next, ll=ll->next) + escassign(e, ll->n, lr->n); + if(lr || ll) + fatal("esc oas2func"); break; case ORETURN: - for(ll=n->list; ll; ll=ll->next) - escassign(&theSink, ll->n); + ll=n->list; + if(count(n->list) == 1 && curfn->type->outtuple > 1) { + // OAS2FUNC in disguise + // esccall already done on n->list->n + // tie n->list->n->escretval to curfn->dcl PPARAMOUT's + ll = n->list->n->escretval; + } + + for(lr = curfn->dcl; lr && ll; lr=lr->next) { + if (lr->n->op != ONAME || lr->n->class != PPARAMOUT) + continue; + escassign(e, lr->n, ll->n); + ll = ll->next; + } + if (ll != nil) + fatal("esc return list"); break; case OPANIC: // Argument could leak through recover. - escassign(&theSink, n->left); + escassign(e, &e->theSink, n->left); break; case OAPPEND: if(!n->isddd) for(ll=n->list->next; ll; ll=ll->next) - escassign(&theSink, ll->n); // lose track of assign to dereference - break; - - case OCALLMETH: - case OCALLFUNC: - case OCALLINTER: - esccall(n); + escassign(e, &e->theSink, ll->n); // lose track of assign to dereference break; case OCONV: case OCONVNOP: case OCONVIFACE: - escassign(n, n->left); + escassign(e, n, n->left); break; case OARRAYLIT: if(isslice(n->type)) { n->esc = EscNone; // until proven otherwise - noesc = list(noesc, n); - n->escloopdepth = loopdepth; + e->noesc = list(e->noesc, n); + n->escloopdepth = e->loopdepth; // Values make it to memory, lose track. for(ll=n->list; ll; ll=ll->next) - escassign(&theSink, ll->n->right); + escassign(e, &e->theSink, ll->n->right); } else { // Link values to array. for(ll=n->list; ll; ll=ll->next) - escassign(n, ll->n->right); + escassign(e, n, ll->n->right); } break; case OSTRUCTLIT: // Link values to struct. for(ll=n->list; ll; ll=ll->next) - escassign(n, ll->n->right); + escassign(e, n, ll->n->right); break; case OPTRLIT: n->esc = EscNone; // until proven otherwise - noesc = list(noesc, n); - n->escloopdepth = loopdepth; + e->noesc = list(e->noesc, n); + n->escloopdepth = e->loopdepth; // Contents make it to memory, lose track. - escassign(&theSink, n->left); + escassign(e, &e->theSink, n->left); break; case OMAPLIT: n->esc = EscNone; // until proven otherwise - noesc = list(noesc, n); - n->escloopdepth = loopdepth; + e->noesc = list(e->noesc, n); + n->escloopdepth = e->loopdepth; // Keys and values make it to memory, lose track. for(ll=n->list; ll; ll=ll->next) { - escassign(&theSink, ll->n->left); - escassign(&theSink, ll->n->right); + escassign(e, &e->theSink, ll->n->left); + escassign(e, &e->theSink, ll->n->right); } break; case OCLOSURE: + // Link addresses of captured variables to closure. + for(ll=n->cvars; ll; ll=ll->next) { + if(ll->n->op == OXXX) // unnamed out argument; see dcl.c:/^funcargs + continue; + a = nod(OADDR, ll->n->closure, N); + a->lineno = ll->n->lineno; + a->escloopdepth = e->loopdepth; + typecheck(&a, Erv); + escassign(e, n, a); + } + // fallthrough case OADDR: case OMAKECHAN: case OMAKEMAP: case OMAKESLICE: case ONEW: - n->escloopdepth = loopdepth; + n->escloopdepth = e->loopdepth; n->esc = EscNone; // until proven otherwise - noesc = list(noesc, n); + e->noesc = list(e->noesc, n); break; } @@ -407,21 +639,22 @@ esc(Node *n) // evaluated in curfn. For expr==nil, dst must still be examined for // evaluations inside it (e.g *f(x) = y) static void -escassign(Node *dst, Node *src) +escassign(EscState *e, Node *dst, Node *src) { int lno; + NodeList *ll; if(isblank(dst) || dst == N || src == N || src->op == ONONAME || src->op == OXXX) return; if(debug['m'] > 1) - print("%L:[%d] %S escassign: %hN(%hJ) = %hN(%hJ)\n", lineno, loopdepth, + print("%L:[%d] %S escassign: %hN(%hJ) = %hN(%hJ)\n", lineno, e->loopdepth, (curfn && curfn->nname) ? curfn->nname->sym : S, dst, dst, src, src); setlineno(dst); // Analyze lhs of assignment. - // Replace dst with theSink if we can't track it. + // Replace dst with e->theSink if we can't track it. switch(dst->op) { default: dump("dst", dst); @@ -438,31 +671,31 @@ escassign(Node *dst, Node *src) case ONAME: if(dst->class == PEXTERN) - dst = &theSink; + dst = &e->theSink; break; case ODOT: // treat "dst.x = src" as "dst = src" - escassign(dst->left, src); + escassign(e, dst->left, src); return; case OINDEX: if(isfixedarray(dst->left->type)) { - escassign(dst->left, src); + escassign(e, dst->left, src); return; } - dst = &theSink; // lose track of dereference + dst = &e->theSink; // lose track of dereference break; case OIND: case ODOTPTR: - dst = &theSink; // lose track of dereference + dst = &e->theSink; // lose track of dereference break; case OINDEXMAP: // lose track of key and value - escassign(&theSink, dst->right); - dst = &theSink; + escassign(e, &e->theSink, dst->right); + dst = &e->theSink; break; } lno = setlineno(src); - pdepth++; + e->pdepth++; switch(src->op) { case OADDR: // dst = &x @@ -480,7 +713,16 @@ escassign(Node *dst, Node *src) case OMAKESLICE: case ONEW: case OCLOSURE: - escflows(dst, src); + escflows(e, dst, src); + break; + + case OCALLMETH: + case OCALLFUNC: + case OCALLINTER: + // Flowing multiple returns to a single dst happens when + // analyzing "go f(g())": here g() flows to sink (issue 4529). + for(ll=src->escretval; ll; ll=ll->next) + escflows(e, dst, ll->n); break; case ODOT: @@ -498,18 +740,18 @@ escassign(Node *dst, Node *src) case OSLICE: case OSLICEARR: // Conversions, field access, slice all preserve the input value. - escassign(dst, src->left); + escassign(e, dst, src->left); break; case OAPPEND: // Append returns first argument. - escassign(dst, src->list->n); + escassign(e, dst, src->list->n); break; case OINDEX: // Index of array preserves input value. if(isfixedarray(src->left->type)) - escassign(dst, src->left); + escassign(e, dst, src->left); break; case OADD: @@ -529,29 +771,49 @@ escassign(Node *dst, Node *src) // Might be pointer arithmetic, in which case // the operands flow into the result. // TODO(rsc): Decide what the story is here. This is unsettling. - escassign(dst, src->left); - escassign(dst, src->right); + escassign(e, dst, src->left); + escassign(e, dst, src->right); break; - } - pdepth--; + e->pdepth--; lineno = lno; } +static void +escassignfromtag(EscState *e, Strlit *note, NodeList *dsts, Node *src) +{ + int em; + + em = parsetag(note); + + if(em == EscUnknown) { + escassign(e, &e->theSink, src); + return; + } + + for(em >>= EscBits; em && dsts; em >>= 1, dsts=dsts->next) + if(em & 1) + escassign(e, dsts->n, src); + + if (em != 0 && dsts == nil) + fatal("corrupt esc tag %Z or messed up escretval list\n", note); +} -// This is a bit messier than fortunate, pulled out of escassign's big +// This is a bit messier than fortunate, pulled out of esc's big // switch for clarity. We either have the paramnodes, which may be -// connected to other things throug flows or we have the parameter type +// connected to other things through flows or we have the parameter type // nodes, which may be marked "noescape". Navigating the ast is slightly // different for methods vs plain functions and for imported vs // this-package static void -esccall(Node *n) +esccall(EscState *e, Node *n) { NodeList *ll, *lr; Node *a, *fn, *src; Type *t, *fntype; + char buf[40]; + int i; fn = N; switch(n->op) { @@ -579,74 +841,96 @@ esccall(Node *n) ll = n->list; if(n->list != nil && n->list->next == nil) { a = n->list->n; - if(a->type->etype == TSTRUCT && a->type->funarg) { - // f(g()). - // Since f's arguments are g's results and - // all function results escape, we're done. - ll = nil; - } + if(a->type->etype == TSTRUCT && a->type->funarg) // f(g()). + ll = a->escretval; } - if(fn && fn->op == ONAME && fn->class == PFUNC && fn->defn && fn->defn->nbody && fn->ntype) { - // Local function. Incorporate into flow graph. + if(fn && fn->op == ONAME && fn->class == PFUNC && fn->defn && fn->defn->nbody && fn->ntype && fn->defn->esc < EscFuncTagged) { + // function in same mutually recursive group. Incorporate into flow graph. +// print("esc local fn: %N\n", fn->ntype); + if(fn->defn->esc == EscFuncUnknown || n->escretval != nil) + fatal("graph inconsistency"); + + // set up out list on this call node + for(lr=fn->ntype->rlist; lr; lr=lr->next) + n->escretval = list(n->escretval, lr->n->left); // type.rlist -> dclfield -> ONAME (PPARAMOUT) // Receiver. if(n->op != OCALLFUNC) - escassign(fn->ntype->left->left, n->left->left); + escassign(e, fn->ntype->left->left, n->left->left); for(lr=fn->ntype->list; ll && lr; ll=ll->next, lr=lr->next) { src = ll->n; if(lr->n->isddd && !n->isddd) { // Introduce ODDDARG node to represent ... allocation. src = nod(ODDDARG, N, N); - src->escloopdepth = loopdepth; + src->escloopdepth = e->loopdepth; src->lineno = n->lineno; src->esc = EscNone; // until we find otherwise - noesc = list(noesc, src); + e->noesc = list(e->noesc, src); n->right = src; } if(lr->n->left != N) - escassign(lr->n->left, src); + escassign(e, lr->n->left, src); if(src != ll->n) break; } // "..." arguments are untracked for(; ll; ll=ll->next) - escassign(&theSink, ll->n); + escassign(e, &e->theSink, ll->n); + return; } - // Imported function. Use the escape tags. - if(n->op != OCALLFUNC) { - t = getthisx(fntype)->type; - if(!t->note || strcmp(t->note->s, safetag->s) != 0) - escassign(&theSink, n->left->left); + // Imported or completely analyzed function. Use the escape tags. + if(n->escretval != nil) + fatal("esc already decorated call %+N\n", n); + + // set up out list on this call node with dummy auto ONAMES in the current (calling) function. + i = 0; + for(t=getoutargx(fntype)->type; t; t=t->down) { + src = nod(ONAME, N, N); + snprint(buf, sizeof buf, ".dum%d", i++); + src->sym = lookup(buf); + src->type = t->type; + src->class = PAUTO; + src->curfn = curfn; + src->escloopdepth = e->loopdepth; + src->used = 1; + src->lineno = n->lineno; + n->escretval = list(n->escretval, src); } + +// print("esc analyzed fn: %#N (%+T) returning (%+H)\n", fn, fntype, n->escretval); + + // Receiver. + if(n->op != OCALLFUNC) + escassignfromtag(e, getthisx(fntype)->type->note, n->escretval, n->left->left); + for(t=getinargx(fntype)->type; ll; ll=ll->next) { src = ll->n; if(t->isddd && !n->isddd) { // Introduce ODDDARG node to represent ... allocation. src = nod(ODDDARG, N, N); - src->escloopdepth = loopdepth; + src->escloopdepth = e->loopdepth; src->lineno = n->lineno; src->esc = EscNone; // until we find otherwise - noesc = list(noesc, src); + e->noesc = list(e->noesc, src); n->right = src; } - if(!t->note || strcmp(t->note->s, safetag->s) != 0) - escassign(&theSink, src); + escassignfromtag(e, t->note, n->escretval, src); if(src != ll->n) break; t = t->down; } // "..." arguments are untracked for(; ll; ll=ll->next) - escassign(&theSink, ll->n); + escassign(e, &e->theSink, ll->n); } // Store the link src->dst in dst, throwing out some quick wins. static void -escflows(Node *dst, Node *src) +escflows(EscState *e, Node *dst, Node *src) { if(dst == nil || src == nil || dst == src) return; @@ -659,10 +943,10 @@ escflows(Node *dst, Node *src) print("%L::flows:: %hN <- %hN\n", lineno, dst, src); if(dst->escflowsrc == nil) { - dsts = list(dsts, dst); - dstcount++; + e->dsts = list(e->dsts, dst); + e->dstcount++; } - edgecount++; + e->edgecount++; dst->escflowsrc = list(dst->escflowsrc, src); } @@ -673,11 +957,11 @@ escflows(Node *dst, Node *src) // so this address doesn't leak (yet). // If level == 0, it means the /value/ of this node can reach the root of this flood. // so if this node is an OADDR, it's argument should be marked as escaping iff -// it's currfn/loopdepth are different from the flood's root. +// it's currfn/e->loopdepth are different from the flood's root. // Once an object has been moved to the heap, all of it's upstream should be considered // escaping to the global scope. static void -escflood(Node *dst) +escflood(EscState *e, Node *dst) { NodeList *l; @@ -696,45 +980,71 @@ escflood(Node *dst) for(l = dst->escflowsrc; l; l=l->next) { walkgen++; - escwalk(0, dst, l->n); + escwalk(e, 0, dst, l->n); } } +// There appear to be some loops in the escape graph, causing +// arbitrary recursion into deeper and deeper levels. +// Cut this off safely by making minLevel sticky: once you +// get that deep, you cannot go down any further but you also +// cannot go up any further. This is a conservative fix. +// Making minLevel smaller (more negative) would handle more +// complex chains of indirections followed by address-of operations, +// at the cost of repeating the traversal once for each additional +// allowed level when a loop is encountered. Using -2 suffices to +// pass all the tests we have written so far, which we assume matches +// the level of complexity we want the escape analysis code to handle. +#define MinLevel (-2) + static void -escwalk(int level, Node *dst, Node *src) +escwalk(EscState *e, int level, Node *dst, Node *src) { NodeList *ll; - int leaks; + int leaks, newlevel; - if(src->walkgen == walkgen) + if(src->walkgen == walkgen && src->esclevel <= level) return; src->walkgen = walkgen; + src->esclevel = level; if(debug['m']>1) print("escwalk: level:%d depth:%d %.*s %hN(%hJ) scope:%S[%d]\n", - level, pdepth, pdepth, "\t\t\t\t\t\t\t\t\t\t", src, src, + level, e->pdepth, e->pdepth, "\t\t\t\t\t\t\t\t\t\t", src, src, (src->curfn && src->curfn->nname) ? src->curfn->nname->sym : S, src->escloopdepth); - pdepth++; + e->pdepth++; + + // Input parameter flowing to output parameter? + if(dst->op == ONAME && dst->class == PPARAMOUT && dst->vargen <= 20) { + if(src->op == ONAME && src->class == PPARAM && level == 0 && src->curfn == dst->curfn) { + if(src->esc != EscScope && src->esc != EscHeap) { + if(debug['m']) + warnl(src->lineno, "leaking param: %hN to result %S", src, dst->sym); + if((src->esc&EscMask) != EscReturn) + src->esc = EscReturn; + src->esc |= 1<<((dst->vargen-1) + EscBits); + goto recurse; + } + } + } leaks = (level <= 0) && (dst->escloopdepth < src->escloopdepth); switch(src->op) { case ONAME: - if(src->class == PPARAM && leaks && src->esc == EscNone) { + if(src->class == PPARAM && leaks && src->esc != EscHeap) { src->esc = EscScope; if(debug['m']) warnl(src->lineno, "leaking param: %hN", src); } - // handle the missing flow ref <- orig - // a paramref is automagically dereferenced, and taking its - // address produces the address of the original, so all we have to do here - // is keep track of the value flow, so level is unchanged. - // alternatively, we could have substituted PPARAMREFs with their ->closure in esc/escassign/flow, + + // Treat a PPARAMREF closure variable as equivalent to the + // original variable. if(src->class == PPARAMREF) { if(leaks && debug['m']) warnl(src->lineno, "leaking closure reference %hN", src); - escwalk(level, dst, src->closure); + escwalk(e, level, dst, src->closure); } break; @@ -746,7 +1056,10 @@ escwalk(int level, Node *dst, Node *src) if(debug['m']) warnl(src->lineno, "%hN escapes to heap", src); } - escwalk(level-1, dst, src->left); + newlevel = level; + if(level > MinLevel) + newlevel--; + escwalk(e, newlevel, dst, src->left); break; case OARRAYLIT: @@ -767,32 +1080,53 @@ escwalk(int level, Node *dst, Node *src) } break; + case ODOT: + escwalk(e, level, dst, src->left); + break; + case OINDEX: - if(isfixedarray(src->type)) + if(isfixedarray(src->left->type)) { + escwalk(e, level, dst, src->left); break; + } // fall through case OSLICE: case ODOTPTR: case OINDEXMAP: case OIND: - escwalk(level+1, dst, src->left); + newlevel = level; + if(level > MinLevel) + newlevel++; + escwalk(e, newlevel, dst, src->left); } +recurse: for(ll=src->escflowsrc; ll; ll=ll->next) - escwalk(level, dst, ll->n); + escwalk(e, level, dst, ll->n); - pdepth--; + e->pdepth--; } static void -esctag(Node *func) +esctag(EscState *e, Node *func) { Node *savefn; NodeList *ll; + Type *t; + + USED(e); + func->esc = EscFuncTagged; - // External functions must be assumed unsafe. - if(func->nbody == nil) + // External functions are assumed unsafe, + // unless //go:noescape is given before the declaration. + if(func->nbody == nil) { + if(func->noescape) { + for(t=getinargx(func->type)->type; t; t=t->down) + if(haspointers(t->type)) + t->note = mktag(EscNone); + } return; + } savefn = curfn; curfn = func; @@ -801,10 +1135,12 @@ esctag(Node *func) if(ll->n->op != ONAME || ll->n->class != PPARAM) continue; - switch (ll->n->esc) { + switch (ll->n->esc&EscMask) { case EscNone: // not touched by escflood + case EscReturn: if(haspointers(ll->n->type)) // don't bother tagging for scalars - ll->n->paramfld->note = safetag; + ll->n->paramfld->note = mktag(ll->n->esc); + break; case EscHeap: // touched by escflood, moved to heap case EscScope: // touched by escflood, value leaves scope break; diff --git a/src/cmd/gc/export.c b/src/cmd/gc/export.c index bbed8ae36..b7311665a 100644 --- a/src/cmd/gc/export.c +++ b/src/cmd/gc/export.c @@ -22,22 +22,8 @@ exportsym(Node *n) } n->sym->flags |= SymExport; - exportlist = list(exportlist, n); -} - -// Mark n's symbol as package-local -static void -packagesym(Node *n) -{ - if(n == N || n->sym == S) - return; - if(n->sym->flags & (SymExport|SymPackage)) { - if(n->sym->flags & SymExport) - yyerror("export/package mismatch: %S", n->sym); - return; - } - n->sym->flags |= SymPackage; - + if(debug['E']) + print("export symbol %S\n", n->sym); exportlist = list(exportlist, n); } @@ -58,6 +44,18 @@ initname(char *s) return strcmp(s, "init") == 0; } +// exportedsym returns whether a symbol will be visible +// to files that import our package. +static int +exportedsym(Sym *sym) +{ + // Builtins are visible everywhere. + if(sym->pkg == builtinpkg || sym->origpkg == builtinpkg) + return 1; + + return sym->pkg == localpkg && exportname(sym->name); +} + void autoexport(Node *n, int ctxt) { @@ -67,10 +65,9 @@ autoexport(Node *n, int ctxt) return; if(n->ntype && n->ntype->op == OTFUNC && n->ntype->left) // method return; - if(exportname(n->sym->name) || initname(n->sym->name)) + // -A is for cmd/gc/mkbuiltin script, so export everything + if(debug['A'] || exportname(n->sym->name) || initname(n->sym->name)) exportsym(n); - else - packagesym(n); } static void @@ -104,36 +101,60 @@ reexportdep(Node *n) if(!n) return; -// print("reexportdep %+hN\n", n); + //print("reexportdep %+hN\n", n); switch(n->op) { case ONAME: switch(n->class&~PHEAP) { case PFUNC: // methods will be printed along with their type + // nodes for T.Method expressions + if(n->left && n->left->op == OTYPE) + break; + // nodes for method calls. if(!n->type || n->type->thistuple > 0) break; // fallthrough case PEXTERN: - if (n->sym && n->sym->pkg != localpkg && n->sym->pkg != builtinpkg) + if(n->sym && !exportedsym(n->sym)) { + if(debug['E']) + print("reexport name %S\n", n->sym); exportlist = list(exportlist, n); + } } break; + case ODCL: + // Local variables in the bodies need their type. + t = n->left->type; + if(t != types[t->etype] && t != idealbool && t != idealstring) { + if(isptr[t->etype]) + t = t->type; + if(t && t->sym && t->sym->def && !exportedsym(t->sym)) { + if(debug['E']) + print("reexport type %S from declaration\n", t->sym); + exportlist = list(exportlist, t->sym->def); + } + } + break; case OLITERAL: t = n->type; if(t != types[n->type->etype] && t != idealbool && t != idealstring) { if(isptr[t->etype]) t = t->type; - if (t && t->sym && t->sym->def && t->sym->pkg != localpkg && t->sym->pkg != builtinpkg) { -// print("reexport literal type %+hN\n", t->sym->def); + if(t && t->sym && t->sym->def && !exportedsym(t->sym)) { + if(debug['E']) + print("reexport literal type %S\n", t->sym); exportlist = list(exportlist, t->sym->def); } } // fallthrough case OTYPE: - if (n->sym && n->sym->pkg != localpkg && n->sym->pkg != builtinpkg) + if(n->sym && !exportedsym(n->sym)) { + if(debug['E']) + print("reexport literal/type %S\n", n->sym); exportlist = list(exportlist, n); + } break; // for operations that need a type when rendered, put the type on the export list. @@ -141,13 +162,15 @@ reexportdep(Node *n) case OCONVIFACE: case OCONVNOP: case ODOTTYPE: + case ODOTTYPE2: case OSTRUCTLIT: case OPTRLIT: t = n->type; if(!t->sym && t->type) t = t->type; - if (t && t->sym && t->sym->def && t->sym->pkg != localpkg && t->sym->pkg != builtinpkg) { -// print("reexport convnop %+hN\n", t->sym->def); + if(t && t->sym && t->sym->def && !exportedsym(t->sym)) { + if(debug['E']) + print("reexport type for convnop %S\n", t->sym); exportlist = list(exportlist, t->sym->def); } break; @@ -207,10 +230,11 @@ dumpexportvar(Sym *s) // currently that can leave unresolved ONONAMEs in import-dot-ed packages in the wrong package if(debug['l'] < 2) typecheckinl(n); - Bprint(bout, "\tfunc %#S%#hT { %#H }\n", s, t, n->inl); + // NOTE: The space after %#S here is necessary for ld's export data parser. + Bprint(bout, "\tfunc %#S %#hT { %#H }\n", s, t, n->inl); reexportdeplist(n->inl); } else - Bprint(bout, "\tfunc %#S%#hT\n", s, t); + Bprint(bout, "\tfunc %#S %#hT\n", s, t); } else Bprint(bout, "\tvar %#S %#T\n", s, t); } @@ -262,15 +286,17 @@ dumpexporttype(Type *t) Bprint(bout, "\ttype %#S %#lT\n", t->sym, t); for(i=0; i<n; i++) { f = m[i]; + if(f->nointerface) + Bprint(bout, "\t//go:nointerface\n"); if (f->type->nname && f->type->nname->inl) { // nname was set by caninl // when lazily typechecking inlined bodies, some re-exported ones may not have been typechecked yet. // currently that can leave unresolved ONONAMEs in import-dot-ed packages in the wrong package if(debug['l'] < 2) typecheckinl(f->type->nname); - Bprint(bout, "\tfunc (%#T) %#hhS%#hT { %#H }\n", getthisx(f->type)->type, f->sym, f->type, f->type->nname->inl); + Bprint(bout, "\tfunc (%#T) %#hhS %#hT { %#H }\n", getthisx(f->type)->type, f->sym, f->type, f->type->nname->inl); reexportdeplist(f->type->nname->inl); } else - Bprint(bout, "\tfunc (%#T) %#hhS%#hT\n", getthisx(f->type)->type, f->sym, f->type); + Bprint(bout, "\tfunc (%#T) %#hhS %#hT\n", getthisx(f->type)->type, f->sym, f->type); } } @@ -349,8 +375,12 @@ dumpexport(void) Sym* importsym(Sym *s, int op) { - if(s->def != N && s->def->op != op) - redeclare(s, "during import"); + char *pkgstr; + + if(s->def != N && s->def->op != op) { + pkgstr = smprint("during import \"%Z\"", importpkg->path); + redeclare(s, pkgstr); + } // mark the symbol so it is not reexported if(s->def == N) { @@ -389,6 +419,8 @@ importimport(Sym *s, Strlit *z) // human-readable messages. Pkg *p; + if(isbadimport(z)) + errorexit(); p = mkpkg(z); if(p->name == nil) { p->name = s->name; diff --git a/src/cmd/gc/fmt.c b/src/cmd/gc/fmt.c index 5672c0010..ab81e6c88 100644 --- a/src/cmd/gc/fmt.c +++ b/src/cmd/gc/fmt.c @@ -228,6 +228,7 @@ goopnames[] = [ORANGE] = "range", [OREAL] = "real", [ORECV] = "<-", + [ORECOVER] = "recover", [ORETURN] = "return", [ORSH] = ">>", [OSELECT] = "select", @@ -289,7 +290,7 @@ Jconv(Fmt *fp) fmtprint(fp, " l(%d)", n->lineno); if(!c && n->xoffset != BADWIDTH) - fmtprint(fp, " x(%lld%+d)", n->xoffset, n->stkdelta); + fmtprint(fp, " x(%lld%+lld)", n->xoffset, n->stkdelta); if(n->class != 0) { s = ""; @@ -361,6 +362,8 @@ Vconv(Fmt *fp) switch(v->ctype) { case CTINT: + if((fp->flags & FmtSharp) || fmtmode == FExp) + return fmtprint(fp, "%#B", v->u.xval); return fmtprint(fp, "%B", v->u.xval); case CTRUNE: x = mpgetfix(v->u.xval); @@ -377,8 +380,14 @@ Vconv(Fmt *fp) return fmtprint(fp, "%#F", v->u.fval); case CTCPLX: if((fp->flags & FmtSharp) || fmtmode == FExp) - return fmtprint(fp, "(%F+%F)", &v->u.cval->real, &v->u.cval->imag); - return fmtprint(fp, "(%#F + %#Fi)", &v->u.cval->real, &v->u.cval->imag); + return fmtprint(fp, "(%F+%Fi)", &v->u.cval->real, &v->u.cval->imag); + if(mpcmpfltc(&v->u.cval->real, 0) == 0) + return fmtprint(fp, "%#Fi", &v->u.cval->imag); + if(mpcmpfltc(&v->u.cval->imag, 0) == 0) + return fmtprint(fp, "%#F", &v->u.cval->real); + if(mpcmpfltc(&v->u.cval->imag, 0) < 0) + return fmtprint(fp, "(%#F%#Fi)", &v->u.cval->real, &v->u.cval->imag); + return fmtprint(fp, "(%#F+%#Fi)", &v->u.cval->real, &v->u.cval->imag); case CTSTR: return fmtprint(fp, "\"%Z\"", v->u.sval); case CTBOOL: @@ -388,7 +397,7 @@ Vconv(Fmt *fp) case CTNIL: return fmtstrcpy(fp, "nil"); } - return fmtprint(fp, "<%d>", v->ctype); + return fmtprint(fp, "<ctype=%d>", v->ctype); } // Fmt "%Z": escaped string literals @@ -516,6 +525,8 @@ symfmt(Fmt *fp, Sym *s) return fmtprint(fp, "%s.%s", s->pkg->name, s->name); // dcommontype, typehash return fmtprint(fp, "%s.%s", s->pkg->prefix, s->name); // (methodsym), typesym, weaksym case FExp: + if(s->name && s->name[0] == '.') + fatal("exporting synthetic symbol %s", s->name); if(s->pkg != builtinpkg) return fmtprint(fp, "@\"%Z\".%s", s->pkg->path, s->name); } @@ -711,12 +722,21 @@ typefmt(Fmt *fp, Type *t) case TFIELD: if(!(fp->flags&FmtShort)) { s = t->sym; - // Take the name from the original, lest we substituted it with .anon%d - if (t->nname && (fmtmode == FErr || fmtmode == FExp)) - s = t->nname->orig->sym; + + // Take the name from the original, lest we substituted it with ~anon%d + if ((fmtmode == FErr || fmtmode == FExp) && t->nname != N) { + if(t->nname->orig != N) { + s = t->nname->orig->sym; + if(s != S && s->name[0] == '~') + s = S; + } else + s = S; + } if(s != S && !t->embedded) { - if(fp->flags&FmtLong) + if(t->funarg) + fmtprint(fp, "%N ", t->nname); + else if(fp->flags&FmtLong) fmtprint(fp, "%hhS ", s); // qualify non-exported names (used on structs, not on funarg) else fmtprint(fp, "%S ", s); @@ -794,6 +814,15 @@ stmtfmt(Fmt *f, Node *n) switch(n->op){ case ODCL: + if(fmtmode == FExp) { + switch(n->left->class&~PHEAP) { + case PPARAM: + case PPARAMOUT: + case PAUTO: + fmtprint(f, "var %N %T", n->left, n->left->type); + goto ret; + } + } fmtprint(f, "var %S %T", n->left->sym, n->left->type); break; @@ -805,6 +834,12 @@ stmtfmt(Fmt *f, Node *n) break; case OAS: + // Don't export "v = <N>" initializing statements, hope they're always + // preceded by the DCL which will be re-parsed and typecheck to reproduce + // the "v = <N>" again. + if(fmtmode == FExp && n->right == N) + break; + if(n->colas && !complexinit) fmtprint(f, "%N := %N", n->left, n->right); else @@ -925,6 +960,7 @@ stmtfmt(Fmt *f, Node *n) break; } +ret: if(extrablock) fmtstrcpy(f, "}"); @@ -962,7 +998,6 @@ static int opprec[] = { [OPAREN] = 8, [OPRINTN] = 8, [OPRINT] = 8, - [ORECV] = 8, [ORUNESTR] = 8, [OSTRARRAYBYTE] = 8, [OSTRARRAYRUNE] = 8, @@ -994,6 +1029,7 @@ static int opprec[] = { [OMINUS] = 7, [OADDR] = 7, [OIND] = 7, + [ORECV] = 7, [OMUL] = 6, [ODIV] = 6, @@ -1055,8 +1091,8 @@ static int exprfmt(Fmt *f, Node *n, int prec) { int nprec; + int ptrlit; NodeList *l; - Type *t; while(n && n->implicit && (n->op == OIND || n->op == OADDR)) n = n->left; @@ -1084,9 +1120,9 @@ exprfmt(Fmt *f, Node *n, int prec) case OLITERAL: // this is a bit of a mess if(fmtmode == FErr && n->sym != S) return fmtprint(f, "%S", n->sym); - if(n->val.ctype == CTNIL) - n = n->orig; // if this node was a nil decorated with at type, print the original naked nil - if(n->type != types[n->type->etype] && n->type != idealbool && n->type != idealstring) { + if(n->val.ctype == CTNIL && n->orig != N && n->orig != n) + return exprfmt(f, n->orig, prec); + if(n->type != T && n->type != types[n->type->etype] && n->type != idealbool && n->type != idealstring) { // Need parens when type begins with what might // be misinterpreted as a unary operator: * or <-. if(isptr[n->type->etype] || (n->type->etype == TCHAN && n->type->chan == Crecv)) @@ -1097,6 +1133,15 @@ exprfmt(Fmt *f, Node *n, int prec) return fmtprint(f, "%V", &n->val); case ONAME: + // Special case: name used as local variable in export. + switch(n->class&~PHEAP){ + case PAUTO: + case PPARAM: + case PPARAMOUT: + if(fmtmode == FExp && n->sym && !isblanksym(n->sym) && n->vargen > 0) + return fmtprint(f, "%S·%d", n->sym, n->vargen); + } + // Special case: explicit name of func (*T) method(...) is turned into pkg.(*T).method, // but for export, this should be rendered as (*pkg.T).meth. // These nodes have the special property that they are names with a left OTYPE and a right ONAME. @@ -1152,12 +1197,25 @@ exprfmt(Fmt *f, Node *n, int prec) case OCLOSURE: if(fmtmode == FErr) return fmtstrcpy(f, "func literal"); - return fmtprint(f, "%T { %H }", n->type, n->nbody); + if(n->nbody) + return fmtprint(f, "%T { %H }", n->type, n->nbody); + return fmtprint(f, "%T { %H }", n->type, n->closure->nbody); case OCOMPLIT: - if(fmtmode == FErr) + ptrlit = n->right != N && n->right->implicit && n->right->type && isptr[n->right->type->etype]; + if(fmtmode == FErr) { + if(n->right != N && n->right->type != T && !n->implicit) { + if(ptrlit) + return fmtprint(f, "&%T literal", n->right->type->type); + else + return fmtprint(f, "%T literal", n->right->type); + } return fmtstrcpy(f, "composite literal"); - return fmtprint(f, "%N{ %,H }", n->right, n->list); + } + if(fmtmode == FExp && ptrlit) + // typecheck has overwritten OIND by OTYPE with pointer type. + return fmtprint(f, "&%T{ %,H }", n->right->type->type, n->list); + return fmtprint(f, "(%N{ %,H })", n->right, n->list); case OPTRLIT: if(fmtmode == FExp && n->left->implicit) @@ -1168,24 +1226,18 @@ exprfmt(Fmt *f, Node *n, int prec) if(fmtmode == FExp) { // requires special handling of field names if(n->implicit) fmtstrcpy(f, "{"); - else - fmtprint(f, "%T{", n->type); + else + fmtprint(f, "(%T{", n->type); for(l=n->list; l; l=l->next) { - // another special case: if n->left is an embedded field of builtin type, - // it needs to be non-qualified. Can't figure that out in %S, so do it here - if(l->n->left->type->embedded) { - t = l->n->left->type->type; - if(t->sym == S) - t = t->type; - fmtprint(f, " %T:%N", t, l->n->right); - } else - fmtprint(f, " %hhS:%N", l->n->left->sym, l->n->right); + fmtprint(f, " %hhS:%N", l->n->left->sym, l->n->right); if(l->next) fmtstrcpy(f, ","); else fmtstrcpy(f, " "); } + if(!n->implicit) + return fmtstrcpy(f, "})"); return fmtstrcpy(f, "}"); } // fallthrough @@ -1196,11 +1248,16 @@ exprfmt(Fmt *f, Node *n, int prec) return fmtprint(f, "%T literal", n->type); if(fmtmode == FExp && n->implicit) return fmtprint(f, "{ %,H }", n->list); - return fmtprint(f, "%T{ %,H }", n->type, n->list); + return fmtprint(f, "(%T{ %,H })", n->type, n->list); case OKEY: - if(n->left && n->right) - return fmtprint(f, "%N:%N", n->left, n->right); + if(n->left && n->right) { + if(fmtmode == FExp && n->left->type && n->left->type->etype == TFIELD) { + // requires special handling of field names + return fmtprint(f, "%hhS:%N", n->left->sym, n->right); + } else + return fmtprint(f, "%N:%N", n->left, n->right); + } if(!n->left && n->right) return fmtprint(f, ":%N", n->right); if(n->left && !n->right) @@ -1260,6 +1317,7 @@ exprfmt(Fmt *f, Node *n, int prec) case OMAKE: case ONEW: case OPANIC: + case ORECOVER: case OPRINT: case OPRINTN: if(n->left) @@ -1408,6 +1466,7 @@ nodedump(Fmt *fp, Node *n) fmtprint(fp, "%O%J", n->op, n); break; case OREGISTER: + case OINDREG: fmtprint(fp, "%O-%R%J", n->op, n->val.u.reg, n); break; case OLITERAL: @@ -1419,6 +1478,10 @@ nodedump(Fmt *fp, Node *n) fmtprint(fp, "%O-%S%J", n->op, n->sym, n); else fmtprint(fp, "%O%J", n->op, n); + if(recur && n->type == T && n->ntype) { + indent(fp); + fmtprint(fp, "%O-ntype%N", n->op, n->ntype); + } break; case OASOP: fmtprint(fp, "%O-%O%J", n->op, n->etype, n); @@ -1629,11 +1692,11 @@ fmtinstallgo(void) void dumplist(char *s, NodeList *l) { - print("%s\n%+H\n", s, l); + print("%s%+H\n", s, l); } void dump(char *s, Node *n) { - print("%s [%p]\n%+N\n", s, n, n); + print("%s [%p]%+N\n", s, n, n); } diff --git a/src/cmd/gc/gen.c b/src/cmd/gc/gen.c index 96e7b526c..5f03d9476 100644 --- a/src/cmd/gc/gen.c +++ b/src/cmd/gc/gen.c @@ -266,6 +266,8 @@ gen(Node *n) Label *lab; int32 wasregalloc; +//dump("gen", n); + lno = setlineno(n); wasregalloc = anyregalloc(); @@ -279,7 +281,7 @@ gen(Node *n) switch(n->op) { default: - fatal("gen: unknown op %N", n); + fatal("gen: unknown op %+hN", n); break; case OCASE: @@ -394,7 +396,7 @@ gen(Node *n) } gen(n->nincr); // contin: incr patch(p1, pc); // test: - bgen(n->ntest, 0, breakpc); // if(!test) goto break + bgen(n->ntest, 0, -1, breakpc); // if(!test) goto break genlist(n->nbody); // body gjmp(continpc); patch(breakpc, pc); // done: @@ -410,7 +412,7 @@ gen(Node *n) p1 = gjmp(P); // goto test p2 = gjmp(P); // p2: goto else patch(p1, pc); // test: - bgen(n->ntest, 0, p2); // if(!test) goto p2 + bgen(n->ntest, 0, -n->likely, p2); // if(!test) goto p2 genlist(n->nbody); // then p3 = gjmp(P); // goto done patch(p2, pc); // else: @@ -509,22 +511,24 @@ ret: void cgen_callmeth(Node *n, int proc) { + Node n2; Node *l; - // generate a rewrite for method call + // generate a rewrite in n2 for the method call // (p.f)(...) goes to (f)(p,...) l = n->left; if(l->op != ODOTMETH) fatal("cgen_callmeth: not dotmethod: %N"); - n->op = OCALLFUNC; - n->left = n->left->right; - n->left->type = l->type; + n2 = *n; + n2.op = OCALLFUNC; + n2.left = l->right; + n2.left->type = l->type; - if(n->left->op == ONAME) - n->left->class = PFUNC; - cgen_call(n, proc); + if(n2.left->op == ONAME) + n2.left->class = PFUNC; + cgen_call(&n2, proc); } /* @@ -631,6 +635,67 @@ cgen_discard(Node *nr) } /* + * clearslim generates code to zero a slim node. + */ +void +clearslim(Node *n) +{ + Node z; + Mpflt zero; + + memset(&z, 0, sizeof(z)); + z.op = OLITERAL; + z.type = n->type; + z.addable = 1; + + switch(simtype[n->type->etype]) { + case TCOMPLEX64: + case TCOMPLEX128: + z.val.u.cval = mal(sizeof(*z.val.u.cval)); + mpmovecflt(&z.val.u.cval->real, 0.0); + mpmovecflt(&z.val.u.cval->imag, 0.0); + break; + + case TFLOAT32: + case TFLOAT64: + mpmovecflt(&zero, 0.0); + z.val.ctype = CTFLT; + z.val.u.fval = &zero; + break; + + case TPTR32: + case TPTR64: + case TCHAN: + case TMAP: + z.val.ctype = CTNIL; + break; + + case TBOOL: + z.val.ctype = CTBOOL; + break; + + case TINT8: + case TINT16: + case TINT32: + case TINT64: + case TUINT8: + case TUINT16: + case TUINT32: + case TUINT64: + z.val.ctype = CTINT; + z.val.u.xval = mal(sizeof(*z.val.u.xval)); + mpmovecfix(z.val.u.xval, 0); + break; + + default: + fatal("clearslim called on type %T", n->type); + } + + ullmancalc(&z); + cgen(&z, n); +} + +/* * generate assignment: * nl = nr * nr == N means zero nl. @@ -638,9 +703,7 @@ cgen_discard(Node *nr) void cgen_as(Node *nl, Node *nr) { - Node nc; Type *tl; - int iszer; if(debug['g']) { dump("cgen_as", nl); @@ -655,7 +718,6 @@ cgen_as(Node *nl, Node *nr) return; } - iszer = 0; if(nr == N || isnil(nr)) { // externals and heaps should already be clear if(nr == N) { @@ -670,59 +732,10 @@ cgen_as(Node *nl, Node *nr) return; if(isfat(tl)) { clearfat(nl); - goto ret; - } - - /* invent a "zero" for the rhs */ - iszer = 1; - nr = &nc; - memset(nr, 0, sizeof(*nr)); - switch(simtype[tl->etype]) { - default: - fatal("cgen_as: tl %T", tl); - break; - - case TINT8: - case TUINT8: - case TINT16: - case TUINT16: - case TINT32: - case TUINT32: - case TINT64: - case TUINT64: - nr->val.u.xval = mal(sizeof(*nr->val.u.xval)); - mpmovecfix(nr->val.u.xval, 0); - nr->val.ctype = CTINT; - break; - - case TFLOAT32: - case TFLOAT64: - nr->val.u.fval = mal(sizeof(*nr->val.u.fval)); - mpmovecflt(nr->val.u.fval, 0.0); - nr->val.ctype = CTFLT; - break; - - case TBOOL: - nr->val.u.bval = 0; - nr->val.ctype = CTBOOL; - break; - - case TPTR32: - case TPTR64: - nr->val.ctype = CTNIL; - break; - - case TCOMPLEX64: - case TCOMPLEX128: - nr->val.u.cval = mal(sizeof(*nr->val.u.cval)); - mpmovecflt(&nr->val.u.cval->real, 0.0); - mpmovecflt(&nr->val.u.cval->imag, 0.0); - break; + return; } - nr->op = OLITERAL; - nr->type = tl; - nr->addable = 1; - ullmancalc(nr); + clearslim(nl); + return; } tl = nl->type; @@ -730,11 +743,88 @@ cgen_as(Node *nl, Node *nr) return; cgen(nr, nl); - if(iszer && nl->addable) - gused(nl); +} -ret: - ; +/* + * generate: + * res = iface{typ, data} + * n->left is typ + * n->right is data + */ +void +cgen_eface(Node *n, Node *res) +{ + /* + * the right node of an eface may contain function calls that uses res as an argument, + * so it's important that it is done first + */ + Node dst; + dst = *res; + dst.type = types[tptr]; + dst.xoffset += widthptr; + cgen(n->right, &dst); + dst.xoffset -= widthptr; + cgen(n->left, &dst); +} + +/* + * generate: + * res = s[lo, hi]; + * n->left is s + * n->list is (cap(s)-lo(TUINT), hi-lo(TUINT)[, lo*width(TUINTPTR)]) + * caller (cgen) guarantees res is an addable ONAME. + */ +void +cgen_slice(Node *n, Node *res) +{ + Node src, dst, *cap, *len, *offs, *add; + + cap = n->list->n; + len = n->list->next->n; + offs = N; + if(n->list->next->next) + offs = n->list->next->next->n; + + // dst.len = hi [ - lo ] + dst = *res; + dst.xoffset += Array_nel; + dst.type = types[simtype[TUINT]]; + cgen(len, &dst); + + if(n->op != OSLICESTR) { + // dst.cap = cap [ - lo ] + dst = *res; + dst.xoffset += Array_cap; + dst.type = types[simtype[TUINT]]; + cgen(cap, &dst); + } + + // dst.array = src.array [ + lo *width ] + dst = *res; + dst.xoffset += Array_array; + dst.type = types[TUINTPTR]; + + if(n->op == OSLICEARR) { + if(!isptr[n->left->type->etype]) + fatal("slicearr is supposed to work on pointer: %+N\n", n); + checkref(n->left); + } + + if(isnil(n->left)) { + tempname(&src, n->left->type); + cgen(n->left, &src); + } else + src = *n->left; + src.xoffset += Array_array; + src.type = types[TUINTPTR]; + + if(offs == N) { + cgen(&src, &dst); + } else { + add = nod(OADD, &src, offs); + typecheck(&add, Erv); + cgen(add, &dst); + } } /* diff --git a/src/cmd/gc/go.errors b/src/cmd/gc/go.errors index e29cfff5b..68a5e5af3 100644 --- a/src/cmd/gc/go.errors +++ b/src/cmd/gc/go.errors @@ -65,6 +65,9 @@ static struct { % loadsys package imports LVAR LNAME '=' LNAME '{' LNAME ';' "need trailing comma before newline in composite literal", + % loadsys package imports LVAR LNAME '=' comptype '{' LNAME ';' + "need trailing comma before newline in composite literal", + % loadsys package imports LFUNC LNAME '(' ')' '{' LFUNC LNAME "nested func not allowed", diff --git a/src/cmd/gc/go.h b/src/cmd/gc/go.h index 43bd68793..f86c152f2 100644 --- a/src/cmd/gc/go.h +++ b/src/cmd/gc/go.h @@ -137,6 +137,7 @@ typedef struct Label Label; struct Type { uchar etype; + uchar nointerface; uchar chan; uchar trecur; // to detect loops uchar printed; @@ -146,7 +147,7 @@ struct Type uchar copyany; uchar local; // created in this file uchar deferwidth; - uchar broke; + uchar broke; // broken type definition. uchar isddd; // TFIELD is ... argument uchar align; @@ -170,21 +171,25 @@ struct Type vlong argwid; // most nodes - Type* type; - vlong width; // offset in TFIELD, width in all others + Type* type; // actual type for TFIELD, element type for TARRAY, TCHAN, TMAP, TPTRxx + vlong width; // offset in TFIELD, width in all others // TFIELD - Type* down; // also used in TMAP + Type* down; // next struct field, also key type in TMAP + Type* outer; // outer struct Strlit* note; // literal string annotation // TARRAY - int32 bound; // negative is dynamic array + vlong bound; // negative is dynamic array int32 maplineno; // first use of TFORW as map key int32 embedlineno; // first use of TFORW as embedded type // for TFORW, where to copy the eventual value to NodeList *copyto; + + // for usefield + Node *lastfn; }; #define T ((Type*)0) @@ -215,7 +220,10 @@ enum EscHeap, EscScope, EscNone, + EscReturn, EscNever, + EscBits = 4, + EscMask = (1<<EscBits) - 1, }; struct Node @@ -233,16 +241,19 @@ struct Node NodeList* rlist; uchar op; + uchar nointerface; uchar ullman; // sethi/ullman number uchar addable; // type of addressability - 0 is not addressable uchar trecur; // to detect loops uchar etype; // op for OASOP, etype for OTYPE, exclam for export + uchar bounded; // bounds check unnecessary uchar class; // PPARAM, PAUTO, PEXTERN, etc uchar method; // OCALLMETH name uchar embedded; // ODCLFIELD embedded type uchar colas; // OAS resulting from := uchar diag; // already printed error about this uchar esc; // EscXXX + uchar noescape; // func arguments do not escape uchar funcdepth; uchar builtin; // built-in name, like len or close uchar walkdef; @@ -256,10 +267,10 @@ struct Node uchar implicit; uchar addrtaken; // address taken, even if not moved to heap uchar dupok; // duplicate definitions ok (for func) + schar likely; // likeliness of if statement // most nodes Type* type; - Type* realtype; // as determined by typecheck Node* orig; // original form, for printing, and tracking copies of ONAMEs // func @@ -279,7 +290,7 @@ struct Node Node* defn; // ONAME: initializing assignment; OLABEL: labeled statement Node* pack; // real package for import . names Node* curfn; // function for local variables - Type* paramfld; // TFIELD for this PPARAM + Type* paramfld; // TFIELD for this PPARAM; also for ODOT, curfn // ONAME func param with PHEAP Node* heapaddr; // temp holding heap address of param @@ -301,17 +312,19 @@ struct Node // Escape analysis. NodeList* escflowsrc; // flow(this, src) - int escloopdepth; // -1: global, 0: not set, function top level:1, increased inside function for every loop or label to mark scopes + NodeList* escretval; // on OCALLxxx, list of dummy return values + int escloopdepth; // -1: global, 0: return variables, 1:function top level, increased inside function for every loop or label to mark scopes Sym* sym; // various int32 vargen; // unique name for OTYPE/ONAME int32 lineno; int32 endlineno; vlong xoffset; - int32 stkdelta; // offset added by stack frame compaction phase. + vlong stkdelta; // offset added by stack frame compaction phase. int32 ostk; int32 iota; uint32 walkgen; + int32 esclevel; }; #define N ((Node*)0) @@ -345,6 +358,7 @@ enum SymExported = 1<<2, // already written out by export SymUniq = 1<<3, SymSiggen = 1<<4, + SymGcgen = 1<<5, }; struct Sym @@ -362,6 +376,7 @@ struct Sym Label* label; // corresponding label (ephemeral) int32 block; // blocknumber to catch redeclaration int32 lastlineno; // last declaration for diagnostic + Pkg* origpkg; // original package for . import }; #define S ((Sym*)0) @@ -374,6 +389,7 @@ struct Pkg Sym* pathsym; char* prefix; // escaped path for use in symbol table Pkg* link; + uchar imported; // export data of this package was parsed char exported; // import line written in export data char direct; // imported directly }; @@ -398,102 +414,171 @@ struct Hist }; #define H ((Hist*)0) +// Node ops. enum { OXXX, // names - ONAME, - ONONAME, - OTYPE, - OPACK, - OLITERAL, - - // exprs - OADD, OSUB, OOR, OXOR, OADDSTR, - OADDR, - OANDAND, - OAPPEND, - OARRAYBYTESTR, OARRAYRUNESTR, - OSTRARRAYBYTE, OSTRARRAYRUNE, - OAS, OAS2, OAS2FUNC, OAS2RECV, OAS2MAPR, OAS2DOTTYPE, - OASOP, - OBAD, - OCALL, OCALLFUNC, OCALLMETH, OCALLINTER, - OCAP, - OCLOSE, - OCLOSURE, - OCMPIFACE, OCMPSTR, - OCOMPLIT, OMAPLIT, OSTRUCTLIT, OARRAYLIT, OPTRLIT, - OCONV, OCONVIFACE, OCONVNOP, - OCOPY, - ODCL, ODCLFUNC, ODCLFIELD, ODCLCONST, ODCLTYPE, - ODELETE, - ODOT, ODOTPTR, ODOTMETH, ODOTINTER, OXDOT, - ODOTTYPE, - ODOTTYPE2, - OEQ, ONE, OLT, OLE, OGE, OGT, - OIND, - OINDEX, OINDEXMAP, - OKEY, OPARAM, - OLEN, - OMAKE, OMAKECHAN, OMAKEMAP, OMAKESLICE, - OHMUL, ORRC, OLRC, // high-mul and rotate-carry - OMUL, ODIV, OMOD, OLSH, ORSH, OAND, OANDNOT, - ONEW, - ONOT, OCOM, OPLUS, OMINUS, - OOROR, - OPANIC, OPRINT, OPRINTN, - OPAREN, - OSEND, - OSLICE, OSLICEARR, OSLICESTR, - ORECOVER, - ORECV, - ORUNESTR, - OSELRECV, - OSELRECV2, - OIOTA, - OREAL, OIMAG, OCOMPLEX, - - // stmts - OBLOCK, - OBREAK, - OCASE, OXCASE, - OCONTINUE, - ODEFER, - OEMPTY, - OFALL, OXFALL, - OFOR, - OGOTO, - OIF, - OLABEL, - OPROC, - ORANGE, - ORETURN, - OSELECT, - OSWITCH, - OTYPESW, // l = r.(type) + ONAME, // var, const or func name + ONONAME, // unnamed arg or return value: f(int, string) (int, error) { etc } + OTYPE, // type name + OPACK, // import + OLITERAL, // literal + + // expressions + OADD, // x + y + OSUB, // x - y + OOR, // x | y + OXOR, // x ^ y + OADDSTR, // s + "foo" + OADDR, // &x + OANDAND, // b0 && b1 + OAPPEND, // append + OARRAYBYTESTR, // string(bytes) + OARRAYRUNESTR, // string(runes) + OSTRARRAYBYTE, // []byte(s) + OSTRARRAYRUNE, // []rune(s) + OAS, // x = y or x := y + OAS2, // x, y, z = xx, yy, zz + OAS2FUNC, // x, y = f() + OAS2RECV, // x, ok = <-c + OAS2MAPR, // x, ok = m["foo"] + OAS2DOTTYPE, // x, ok = I.(int) + OASOP, // x += y + OCALL, // function call, method call or type conversion, possibly preceded by defer or go. + OCALLFUNC, // f() + OCALLMETH, // t.Method() + OCALLINTER, // err.Error() + OCAP, // cap + OCLOSE, // close + OCLOSURE, // f = func() { etc } + OCMPIFACE, // err1 == err2 + OCMPSTR, // s1 == s2 + OCOMPLIT, // composite literal, typechecking may convert to a more specific OXXXLIT. + OMAPLIT, // M{"foo":3, "bar":4} + OSTRUCTLIT, // T{x:3, y:4} + OARRAYLIT, // [2]int{3, 4} + OPTRLIT, // &T{x:3, y:4} + OCONV, // var i int; var u uint; i = int(u) + OCONVIFACE, // I(t) + OCONVNOP, // type Int int; var i int; var j Int; i = int(j) + OCOPY, // copy + ODCL, // var x int + ODCLFUNC, // func f() or func (r) f() + ODCLFIELD, // struct field, interface field, or func/method argument/return value. + ODCLCONST, // const pi = 3.14 + ODCLTYPE, // type Int int + ODELETE, // delete + ODOT, // t.x + ODOTPTR, // p.x that is implicitly (*p).x + ODOTMETH, // t.Method + ODOTINTER, // err.Error + OXDOT, // t.x, typechecking may convert to a more specific ODOTXXX. + ODOTTYPE, // e = err.(MyErr) + ODOTTYPE2, // e, ok = err.(MyErr) + OEQ, // x == y + ONE, // x != y + OLT, // x < y + OLE, // x <= y + OGE, // x >= y + OGT, // x > y + OIND, // *p + OINDEX, // a[i] + OINDEXMAP, // m[s] + OKEY, // The x:3 in t{x:3, y:4}, the 1:2 in a[1:2], the 2:20 in [3]int{2:20}, etc. + OPARAM, // The on-stack copy of a parameter or return value that escapes. + OLEN, // len + OMAKE, // make, typechecking may convert to a more specfic OMAKEXXX. + OMAKECHAN, // make(chan int) + OMAKEMAP, // make(map[string]int) + OMAKESLICE, // make([]int, 0) + OMUL, // x * y + ODIV, // x / y + OMOD, // x % y + OLSH, // x << u + ORSH, // x >> u + OAND, // x & y + OANDNOT, // x &^ y + ONEW, // new + ONOT, // !b + OCOM, // ^x + OPLUS, // +x + OMINUS, // -y + OOROR, // b1 || b2 + OPANIC, // panic + OPRINT, // print + OPRINTN, // println + OPAREN, // (x) + OSEND, // c <- x + OSLICE, // v[1:2], typechecking may convert to a more specfic OSLICEXXX. + OSLICEARR, // a[1:2] + OSLICESTR, // s[1:2] + ORECOVER, // recover + ORECV, // <-c + ORUNESTR, // string(i) + OSELRECV, // case x = <-c: + OSELRECV2, // case x, ok = <-c: + OIOTA, // iota + OREAL, // real + OIMAG, // imag + OCOMPLEX, // complex + + // statements + OBLOCK, // block of code + OBREAK, // break + OCASE, // case, after being verified by swt.c's casebody. + OXCASE, // case, before verification. + OCONTINUE, // continue + ODEFER, // defer + OEMPTY, // no-op + OFALL, // fallthrough, after being verified by swt.c's casebody. + OXFALL, // fallthrough, before verification. + OFOR, // for + OGOTO, // goto + OIF, // if + OLABEL, // label: + OPROC, // go + ORANGE, // range + ORETURN, // return + OSELECT, // select + OSWITCH, // switch x + OTYPESW, // switch err.(type) // types - OTCHAN, - OTMAP, - OTSTRUCT, - OTINTER, - OTFUNC, - OTARRAY, - OTPAREN, + OTCHAN, // chan int + OTMAP, // map[string]int + OTSTRUCT, // struct{} + OTINTER, // interface{} + OTFUNC, // func() + OTARRAY, // []int, [8]int, [N]int or [...]int + OTPAREN, // (T) // misc - ODDD, - ODDDARG, - OINLCALL, // intermediary representation of an inlined call - OITAB, // itable word of interface value - - // for back ends - OCMP, ODEC, OEXTEND, OINC, OREGISTER, OINDREG, + ODDD, // func f(args ...int) or f(l...) or var a = [...]int{0, 1, 2}. + ODDDARG, // func f(args ...int), introduced by escape analysis. + OINLCALL, // intermediary representation of an inlined call. + OEFACE, // itable and data words of an empty-interface value. + OITAB, // itable word of an interface value. + OCLOSUREVAR, // variable reference at beginning of closure function + OCFUNC, // reference to c function pointer (not go func value) + + // arch-specific registers + OREGISTER, // a register, such as AX. + OINDREG, // offset plus indirect of a register, such as 8(SP). + + // 386/amd64-specific opcodes + OCMP, // compare: ACMP. + ODEC, // decrement: ADEC. + OINC, // increment: AINC. + OEXTEND, // extend: ACWD/ACDQ/ACQO. + OHMUL, // high mul: AMUL/AIMUL for unsigned/signed (OMUL uses AIMUL for both). + OLROT, // left rotate: AROL. + ORROTC, // right rotate-carry: ARCR. OEND, }; + enum { Txxx, // 0 @@ -539,6 +624,7 @@ enum NTYPE, }; + enum { CTxxx, @@ -562,18 +648,21 @@ enum Cboth = Crecv | Csend, }; +// declaration context enum { Pxxx, - PEXTERN, // declaration context - PAUTO, - PPARAM, - PPARAMOUT, - PPARAMREF, // param passed by reference - PFUNC, + PEXTERN, // global variable + PAUTO, // local variables + PPARAM, // input arguments + PPARAMOUT, // output results + PPARAMREF, // closure variable reference + PFUNC, // global function - PHEAP = 1<<7, + PDISCARD, // discard during parse of duplicate import + + PHEAP = 1<<7, // an extra bit to identify an escaped variable }; enum @@ -606,7 +695,6 @@ typedef struct Var Var; struct Var { vlong offset; - Sym* gotype; Node* node; int width; char name; @@ -756,7 +844,7 @@ EXTERN int safemode; EXTERN char namebuf[NSYMB]; EXTERN char lexbuf[NSYMB]; EXTERN char litbuf[NSYMB]; -EXTERN char debug[256]; +EXTERN int debug[256]; EXTERN Sym* hash[NHASH]; EXTERN Sym* importmyname; // my name for package EXTERN Pkg* localpkg; // package being compiled @@ -764,11 +852,15 @@ EXTERN Pkg* importpkg; // package being imported EXTERN Pkg* structpkg; // package that declared struct, during import EXTERN Pkg* builtinpkg; // fake package for builtins EXTERN Pkg* gostringpkg; // fake pkg for Go strings +EXTERN Pkg* itabpkg; // fake pkg for itab cache EXTERN Pkg* runtimepkg; // package runtime +EXTERN Pkg* racepkg; // package runtime/race EXTERN Pkg* stringpkg; // fake package for C strings -EXTERN Pkg* typepkg; // fake package for runtime type info +EXTERN Pkg* typepkg; // fake package for runtime type info (headers) +EXTERN Pkg* typelinkpkg; // fake package for runtime type info (data) EXTERN Pkg* weaktypepkg; // weak references to runtime type info EXTERN Pkg* unsafepkg; // package unsafe +EXTERN Pkg* trackpkg; // fake package for field tracking EXTERN Pkg* phash[128]; EXTERN int tptr; // either TPTR32 or TPTR64 extern char* runtimeimport; @@ -815,6 +907,7 @@ EXTERN NodeList* externdcl; EXTERN NodeList* closures; EXTERN NodeList* exportlist; EXTERN NodeList* importlist; // imported functions and methods with inlinable bodies +EXTERN NodeList* funcsyms; EXTERN int dclcontext; // PEXTERN/PAUTO EXTERN int incannedimport; EXTERN int statuniqgen; // name generator for static temps @@ -823,8 +916,8 @@ EXTERN int loophack; EXTERN int32 iota; EXTERN NodeList* lastconst; EXTERN Node* lasttype; -EXTERN int32 maxarg; -EXTERN int32 stksize; // stack size for current frame +EXTERN vlong maxarg; +EXTERN vlong stksize; // stack size for current frame EXTERN int32 blockgen; // max block number EXTERN int32 block; // current block number EXTERN int hasdefer; // flag that curfn has defer statetment @@ -832,12 +925,14 @@ EXTERN int hasdefer; // flag that curfn has defer statetment EXTERN Node* curfn; EXTERN int widthptr; +EXTERN int widthint; EXTERN Node* typesw; EXTERN Node* nblank; extern int thechar; extern char* thestring; +EXTERN int use_sse; EXTERN char* hunk; EXTERN int32 nhunk; @@ -846,6 +941,14 @@ EXTERN int32 thunk; EXTERN int funcdepth; EXTERN int typecheckok; EXTERN int compiling_runtime; +EXTERN int compiling_wrappers; +EXTERN int pure_go; +EXTERN int flag_race; +EXTERN int flag_largemodel; +EXTERN int noescape; + +EXTERN int nointerface; +EXTERN int fieldtrack_enabled; /* * y.tab.c @@ -860,7 +963,7 @@ void checkwidth(Type *t); void defercheckwidth(void); void dowidth(Type *t); void resumecheckwidth(void); -uint32 rnd(uint32 o, uint32 r); +vlong rnd(vlong o, vlong r); void typeinit(void); /* @@ -898,9 +1001,11 @@ void defaultlit(Node **np, Type *t); void defaultlit2(Node **lp, Node **rp, int force); void evconst(Node *n); int isconst(Node *n, int ct); +int isgoconst(Node *n); Node* nodcplxlit(Val r, Val i); Node* nodlit(Val v); long nonnegconst(Node *n); +int doesoverflow(Val v, Type *t); void overflow(Val v, Type *t); int smallintconst(Node *n); Val toint(Val v); @@ -910,7 +1015,7 @@ Mpflt* truncfltlit(Mpflt *oldv, Type *t); * cplx.c */ void complexadd(int op, Node *nl, Node *nr, Node *res); -void complexbool(int op, Node *nl, Node *nr, int true, Prog *to); +void complexbool(int op, Node *nl, Node *nr, int true, int likely, Prog *to); void complexgen(Node *n, Node *res); void complexminus(Node *nl, Node *res); void complexmove(Node *f, Node *t); @@ -921,10 +1026,10 @@ void nodfconst(Node *n, Type *t, Mpflt* fval); /* * dcl.c */ -void addmethod(Sym *sf, Type *t, int local); +void addmethod(Sym *sf, Type *t, int local, int nointerface); void addvar(Node *n, Type *t, int ctxt); NodeList* checkarglist(NodeList *all, int input); -Node* colas(NodeList *left, NodeList *right); +Node* colas(NodeList *left, NodeList *right, int32 lno); void colasdefn(NodeList *left, Node *defn); NodeList* constiter(NodeList *vl, Node *t, NodeList *cl); Node* dclname(Sym *s); @@ -954,6 +1059,7 @@ Node* typedcl0(Sym *s); Node* typedcl1(Node *n, Node *t, int local); Node* typenod(Type *t); NodeList* variter(NodeList *vl, Node *t, NodeList *el); +Sym* funcsym(Sym*); /* * esc.c @@ -987,6 +1093,8 @@ void dumplist(char *s, NodeList *l); void addrescapes(Node *n); void cgen_as(Node *nl, Node *nr); void cgen_callmeth(Node *n, int proc); +void cgen_eface(Node* n, Node* res); +void cgen_slice(Node* n, Node* res); void clearlabels(void); void checklabels(void); int dotoffset(Node *n, int *oary, Node **nn); @@ -1115,8 +1223,11 @@ void dumptypestructs(void); Type* methodfunc(Type *f, Type*); Node* typename(Type *t); Sym* typesym(Type *t); +Sym* typenamesym(Type *t); +Sym* tracksym(Type *t); Sym* typesymprefix(char *prefix, Type *t); int haspointers(Type *t); +void usefield(Node*); /* * select.c @@ -1214,6 +1325,7 @@ Node* safeexpr(Node *n, NodeList **init); void saveerrors(void); Node* cheapexpr(Node *n, NodeList **init); Node* localexpr(Node *n, Type *t, NodeList **init); +void saveorignode(Node *n); int32 setlineno(Node *n); void setmaxarg(Type *t); Type* shallow(Type *t); @@ -1274,6 +1386,7 @@ void walkexprlistsafe(NodeList *l, NodeList **init); void walkstmt(Node **np); void walkstmtlist(NodeList *l); Node* conv(Node*, Type*); +int candiscard(Node*); /* * arch-specific ggen.c/gsubr.c/gobj.c/pgen.c @@ -1302,7 +1415,8 @@ EXTERN Node* nodfp; int anyregalloc(void); void betypeinit(void); -void bgen(Node *n, int true, Prog *to); +void bgen(Node *n, int true, int likely, Prog *to); +void checkref(Node*); void cgen(Node*, Node*); void cgen_asop(Node *n); void cgen_call(Node *n, int proc); @@ -1323,8 +1437,8 @@ void gdata(Node*, Node*, int); void gdatacomplex(Node*, Mpcplx*); void gdatastring(Node*, Strlit*); void genembedtramp(Type*, Type*, Sym*, int iface); -void ggloblnod(Node *nam, int32 width); -void ggloblsym(Sym *s, int32 width, int dupok); +void ggloblnod(Node *nam); +void ggloblsym(Sym *s, int32 width, int dupok, int rodata); Prog* gjmp(Prog*); void gused(Node*); int isfat(Type*); @@ -1364,3 +1478,8 @@ void zname(Biobuf *b, Sym *s, int t); #pragma varargck type "V" Val* #pragma varargck type "Y" char* #pragma varargck type "Z" Strlit* + +/* + * racewalk.c + */ +void racewalk(Node *fn); diff --git a/src/cmd/gc/go.y b/src/cmd/gc/go.y index f95058721..794961e8e 100644 --- a/src/cmd/gc/go.y +++ b/src/cmd/gc/go.y @@ -37,8 +37,8 @@ static void fixlbrace(int); // |sed 's/.* //' |9 fmt -l1 |sort |9 fmt -l50 | sed 's/^/%xxx /' %token <val> LLITERAL -%token <i> LASOP -%token <sym> LBREAK LCASE LCHAN LCOLAS LCONST LCONTINUE LDDD +%token <i> LASOP LCOLAS +%token <sym> LBREAK LCASE LCHAN LCONST LCONTINUE LDDD %token <sym> LDEFAULT LDEFER LELSE LFALL LFOR LFUNC LGO LGOTO %token <sym> LIF LIMPORT LINTERFACE LMAP LNAME %token <sym> LPACKAGE LRANGE LRETURN LSELECT LSTRUCT LSWITCH @@ -54,10 +54,10 @@ static void fixlbrace(int); %type <node> stmt ntype %type <node> arg_type %type <node> case caseblock -%type <node> compound_stmt dotname embed expr complitexpr +%type <node> compound_stmt dotname embed expr complitexpr bare_complitexpr %type <node> expr_or_type %type <node> fndcl hidden_fndcl fnliteral -%type <node> for_body for_header for_stmt if_header if_stmt else non_dcl_stmt +%type <node> for_body for_header for_stmt if_header if_stmt non_dcl_stmt %type <node> interfacedcl keyval labelname name %type <node> name_or_type non_expr_type %type <node> new_name dcl_name oexpr typedclname @@ -70,7 +70,7 @@ static void fixlbrace(int); %type <list> xdcl fnbody fnres loop_body dcl_name_list %type <list> new_name_list expr_list keyval_list braced_keyval_list expr_or_type_list xdcl_list -%type <list> oexpr_list caseblock_list stmt_list oarg_type_list_ocomma arg_type_list +%type <list> oexpr_list caseblock_list elseif elseif_list else stmt_list oarg_type_list_ocomma arg_type_list %type <list> interfacedcl_list vardcl vardcl_list structdcl structdcl_list %type <list> common_dcl constdcl constdcl1 constdcl_list typedcl_list @@ -405,6 +405,20 @@ simple_stmt: expr { $$ = $1; + + // These nodes do not carry line numbers. + // Since a bare name used as an expression is an error, + // introduce a wrapper node to give the correct line. + switch($$->op) { + case ONAME: + case ONONAME: + case OTYPE: + case OPACK: + case OLITERAL: + $$ = nod(OPAREN, $$, N); + $$->implicit = 1; + break; + } } | expr LASOP expr { @@ -437,7 +451,7 @@ simple_stmt: $$->left = dclname($1->n->sym); // it's a colas, so must not re-use an oldname. break; } - $$ = colas($1, $3); + $$ = colas($1, $3, $2); } | expr LINC { @@ -496,7 +510,7 @@ case: // done in casebody() markdcl(); $$ = nod(OXCASE, N, N); - $$->list = list1(colas($2, list1($4))); + $$->list = list1(colas($2, list1($4), $3)); } | LDEFAULT ':' { @@ -661,25 +675,56 @@ if_stmt: { $3->nbody = $5; } - else + elseif_list else { - popdcl(); + Node *n; + NodeList *nn; + $$ = $3; - if($7 != N) - $$->nelse = list1($7); + n = $3; + popdcl(); + for(nn = concat($7, $8); nn; nn = nn->next) { + if(nn->n->op == OIF) + popdcl(); + n->nelse = list1(nn->n); + n = nn->n; + } } -else: +elseif: + LELSE LIF { - $$ = N; + markdcl(); } -| LELSE if_stmt + if_header loop_body { - $$ = $2; + if($4->ntest == N) + yyerror("missing condition in if statement"); + $4->nbody = $5; + $$ = list1($4); + } + +elseif_list: + { + $$ = nil; + } +| elseif_list elseif + { + $$ = concat($1, $2); + } + +else: + { + $$ = nil; } | LELSE compound_stmt { - $$ = $2; + NodeList *node; + + node = mal(sizeof *node); + node->n = $2; + node->end = node; + $$ = node; } switch_stmt: @@ -902,7 +947,7 @@ pexpr_no_paren: $$ = nod(OSLICE, $1, nod(OKEY, $3, $5)); } | pseudocall -| convtype '(' expr ')' +| convtype '(' expr ocomma ')' { // conversion $$ = nod(OCALL, $1, N); @@ -943,6 +988,30 @@ keyval: $$ = nod(OKEY, $1, $3); } +bare_complitexpr: + expr + { + // These nodes do not carry line numbers. + // Since a composite literal commonly spans several lines, + // the line number on errors may be misleading. + // Introduce a wrapper node to give the correct line. + $$ = $1; + switch($$->op) { + case ONAME: + case ONONAME: + case OTYPE: + case OPACK: + case OLITERAL: + $$ = nod(OPAREN, $$, N); + $$->implicit = 1; + } + } +| '{' start_complit braced_keyval_list '}' + { + $$ = $2; + $$->list = $3; + } + complitexpr: expr | '{' start_complit braced_keyval_list '}' @@ -966,6 +1035,7 @@ pexpr: case OPACK: case OTYPE: case OLITERAL: + case OTYPESW: $$ = nod(OPAREN, $$, N); } } @@ -1030,10 +1100,16 @@ sym: hidden_importsym: '@' LLITERAL '.' LNAME { + Pkg *p; + if($2.u.sval->len == 0) - $$ = pkglookup($4->name, importpkg); - else - $$ = pkglookup($4->name, mkpkg($2.u.sval)); + p = importpkg; + else { + if(isbadimport($2.u.sval)) + errorexit(); + p = mkpkg($2.u.sval); + } + $$ = pkglookup($4->name, p); } name: @@ -1201,8 +1277,11 @@ xfndcl: $$ = $2; if($$ == N) break; + if(noescape && $3 != nil) + yyerror("can only use //go:noescape with external func implementations"); $$->nbody = $3; $$->endlineno = lineno; + $$->noescape = noescape; funcbody($$); } @@ -1269,6 +1348,7 @@ fndcl: $$->nname = methodname1($$->shortname, rcvr->right); $$->nname->defn = $$; $$->nname->ntype = t; + $$->nname->nointerface = nointerface; declare($$->nname, PFUNC); funchdr($$); @@ -1287,8 +1367,10 @@ hidden_fndcl: importsym(s, ONAME); if(s->def != N && s->def->op == ONAME) { - if(eqtype(t, s->def->type)) + if(eqtype(t, s->def->type)) { + dclcontext = PDISCARD; // since we skip funchdr below break; + } yyerror("inconsistent definition for func %S during import\n\t%T\n\t%T", s, s->def->type, t); } @@ -1304,7 +1386,8 @@ hidden_fndcl: $$->type = functype($2->n, $6, $8); checkwidth($$->type); - addmethod($4, $$->type, 0); + addmethod($4, $$->type, 0, nointerface); + nointerface = 0; funchdr($$); // inl.c's inlnode in on a dotmeth node expects to find the inlineable body as @@ -1381,6 +1464,8 @@ xdcl_list: $$ = concat($1, $2); if(nsyntaxerrors == 0) testdclstack(); + nointerface = 0; + noescape = 0; } vardcl_list: @@ -1719,7 +1804,7 @@ keyval_list: { $$ = list1($1); } -| complitexpr +| bare_complitexpr { $$ = list1($1); } @@ -1727,7 +1812,7 @@ keyval_list: { $$ = list($1, $3); } -| keyval_list ',' complitexpr +| keyval_list ',' bare_complitexpr { $$ = list($1, $3); } @@ -1818,8 +1903,10 @@ hidden_import: } | LFUNC hidden_fndcl fnbody ';' { - if($2 == N) + if($2 == N) { + dclcontext = PEXTERN; // since we skip the funcbody below break; + } $2->inl = $3; @@ -1828,7 +1915,7 @@ hidden_import: if(debug['E']) { print("import [%Z] func %lN \n", importpkg->path, $2); - if(debug['l'] > 2 && $2->inl) + if(debug['m'] > 2 && $2->inl) print("inl body:%+H\n", $2->inl); } } @@ -2039,6 +2126,8 @@ hidden_constant: mpaddfixfix($2->val.u.xval, $4->val.u.xval, 0); break; } + $4->val.u.cval->real = $4->val.u.cval->imag; + mpmovecflt(&$4->val.u.cval->imag, 0.0); $$ = nodcplxlit($2->val, $4->val); } diff --git a/src/cmd/gc/init.c b/src/cmd/gc/init.c index be402cc0c..918d37180 100644 --- a/src/cmd/gc/init.c +++ b/src/cmd/gc/init.c @@ -55,6 +55,10 @@ anyinit(NodeList *n) case ODCLTYPE: case OEMPTY: break; + case OAS: + if(isblank(l->n->left) && candiscard(l->n->right)) + break; + // fall through default: return 1; } diff --git a/src/cmd/gc/inl.c b/src/cmd/gc/inl.c index b2b1faff7..1cc13a304 100644 --- a/src/cmd/gc/inl.c +++ b/src/cmd/gc/inl.c @@ -13,7 +13,7 @@ // 0: disabled // 1: 40-nodes leaf functions, oneliners, lazy typechecking (default) // 2: early typechecking of all imported bodies -// 3: +// 3: allow variadic functions // 4: allow non-leaf functions , (breaks runtime.Caller) // 5: transitive inlining // @@ -39,9 +39,10 @@ static int ishairylist(NodeList *ll, int *budget); // Used by inlcalls static void inlnodelist(NodeList *l); static void inlnode(Node **np); -static void mkinlcall(Node **np, Node *fn); +static void mkinlcall(Node **np, Node *fn, int isddd); static Node* inlvar(Node *n); static Node* retvar(Type *n, int i); +static Node* argvar(Type *n, int i); static Node* newlabel(void); static Node* inlsubst(Node *n); static NodeList* inlsubstlist(NodeList *l); @@ -82,20 +83,18 @@ typecheckinl(Node *fn) Pkg *pkg; int save_safemode, lno; - if(fn->typecheck) - return; - lno = setlineno(fn); - if (debug['m']>2) - print("typecheck import [%S] %lN { %#H }\n", fn->sym, fn, fn->inl); - - // typecheckinl is only used for imported functions; + // typecheckinl is only for imported functions; // their bodies may refer to unsafe as long as the package // was marked safe during import (which was checked then). + // the ->inl of a local function has been typechecked before caninl copied it. pkg = fnpkg(fn); if (pkg == localpkg || pkg == nil) - fatal("typecheckinl on local function %lN", fn); + return; // typecheckinl on local function + + if (debug['m']>2) + print("typecheck import [%S] %lN { %#H }\n", fn->sym, fn, fn->inl); save_safemode = safemode; safemode = 0; @@ -103,7 +102,6 @@ typecheckinl(Node *fn) savefn = curfn; curfn = fn; typechecklist(fn->inl, Etop); - fn->typecheck = 1; curfn = savefn; safemode = save_safemode; @@ -111,10 +109,9 @@ typecheckinl(Node *fn) lineno = lno; } -// Caninl determines whether fn is inlineable. Currently that means: -// fn is exactly 1 statement, either a return or an assignment, and -// some temporary constraints marked TODO. If fn is inlineable, saves -// fn->nbody in fn->inl and substitutes it with a copy. +// Caninl determines whether fn is inlineable. +// If so, caninl saves fn->nbody in fn->inl and substitutes it with a copy. +// fn and ->nbody will already have been typechecked. void caninl(Node *fn) { @@ -131,10 +128,14 @@ caninl(Node *fn) if(fn->nbody == nil) return; + if(fn->typecheck == 0) + fatal("caninl on non-typechecked function %N", fn); + // can't handle ... args yet - for(t=fn->type->type->down->down->type; t; t=t->down) - if(t->isddd) - return; + if(debug['l'] < 3) + for(t=fn->type->type->down->down->type; t; t=t->down) + if(t->isddd) + return; budget = 40; // allowed hairyness if(ishairylist(fn->nbody, &budget)) @@ -145,8 +146,6 @@ caninl(Node *fn) fn->nname->inl = fn->nbody; fn->nbody = inlcopylist(fn->nname->inl); - // nbody will have been typechecked, so we can set this: - fn->typecheck = 1; // hack, TODO, check for better way to link method nodes back to the thing with the ->inl // this is so export can find the body of a method @@ -195,19 +194,11 @@ ishairy(Node *n, int *budget) case OSWITCH: case OPROC: case ODEFER: - case ODCL: // declares locals as globals b/c of @"". qualification case ODCLTYPE: // can't print yet case ODCLCONST: // can't print yet return 1; break; - case OAS: - // x = <N> zero initializing assignments aren't representible in export yet. - // alternatively we may just skip them in printing and hope their DCL printed - // as a var will regenerate it - if(n->right == N) - return 1; - break; } (*budget)--; @@ -366,8 +357,8 @@ inlnode(Node **np) } case OCLOSURE: - // TODO do them here instead of in lex.c phase 6b, so escape analysis - // can avoid more heapmoves. + // TODO do them here (or earlier) instead of in walkcallclosure, + // so escape analysis can avoid more heapmoves. return; } @@ -464,10 +455,10 @@ inlnode(Node **np) if(debug['m']>3) print("%L:call to func %+N\n", n->lineno, n->left); if(n->left->inl) // normal case - mkinlcall(np, n->left); + mkinlcall(np, n->left, n->isddd); else if(n->left->op == ONAME && n->left->left && n->left->left->op == OTYPE && n->left->right && n->left->right->op == ONAME) // methods called as functions if(n->left->sym->def) - mkinlcall(np, n->left->sym->def); + mkinlcall(np, n->left->sym->def, n->isddd); break; case OCALLMETH: @@ -480,7 +471,7 @@ inlnode(Node **np) if(n->left->type->nname == N) fatal("no function definition for [%p] %+T\n", n->left->type, n->left->type); - mkinlcall(np, n->left->type->nname); + mkinlcall(np, n->left->type->nname, n->isddd); break; } @@ -488,10 +479,10 @@ inlnode(Node **np) lineno = lno; } -static void mkinlcall1(Node **np, Node *fn); +static void mkinlcall1(Node **np, Node *fn, int isddd); static void -mkinlcall(Node **np, Node *fn) +mkinlcall(Node **np, Node *fn, int isddd) { int save_safemode; Pkg *pkg; @@ -503,7 +494,7 @@ mkinlcall(Node **np, Node *fn) pkg = fnpkg(fn); if(pkg != localpkg && pkg != nil) safemode = 0; - mkinlcall1(np, fn); + mkinlcall1(np, fn, isddd); safemode = save_safemode; } @@ -519,17 +510,25 @@ tinlvar(Type *t) return nblank; } +static int inlgen; + // if *np is a call, and fn is a function with an inlinable body, substitute *np with an OINLCALL. // On return ninit has the parameter assignments, the nbody is the // inlined function body and list, rlist contain the input, output // parameters. static void -mkinlcall1(Node **np, Node *fn) +mkinlcall1(Node **np, Node *fn, int isddd) { int i; + int chkargcount; Node *n, *call, *saveinlfn, *as, *m; NodeList *dcl, *ll, *ninit, *body; Type *t; + // For variadic fn. + int variadic, varargcount, multiret; + Node *vararg; + NodeList *varargs; + Type *varargtype, *vararrtype; if (fn->inl == nil) return; @@ -556,6 +555,8 @@ mkinlcall1(Node **np, Node *fn) ninit = n->ninit; +//dumplist("ninit pre", ninit); + if (fn->defn) // local function dcl = fn->defn->dcl; else // imported function @@ -567,7 +568,10 @@ mkinlcall1(Node **np, Node *fn) for(ll = dcl; ll; ll=ll->next) if(ll->n->op == ONAME) { ll->n->inlvar = inlvar(ll->n); - ninit = list(ninit, nod(ODCL, ll->n->inlvar, N)); // otherwise gen won't emit the allocations for heapallocs + // Typecheck because inlvar is not necessarily a function parameter. + typecheck(&ll->n->inlvar, Erv); + if ((ll->n->class&~PHEAP) != PAUTO) + ninit = list(ninit, nod(ODCL, ll->n->inlvar, N)); // otherwise gen won't emit the allocations for heapallocs if (ll->n->class == PPARAMOUT) // we rely on the order being correct here inlretvars = list(inlretvars, ll->n->inlvar); } @@ -580,49 +584,118 @@ mkinlcall1(Node **np, Node *fn) inlretvars = list(inlretvars, m); } - // assign arguments to the parameters' temp names - as = N; - if(fn->type->thistuple) { + // assign receiver. + if(fn->type->thistuple && n->left->op == ODOTMETH) { + // method call with a receiver. t = getthisx(fn->type)->type; if(t != T && t->nname != N && !isblank(t->nname) && !t->nname->inlvar) fatal("missing inlvar for %N\n", t->nname); - - if(n->left->op == ODOTMETH) { - if(!n->left->left) - fatal("method call without receiver: %+N", n); - if(t == T) - fatal("method call unknown receiver type: %+N", n); - as = nod(OAS, tinlvar(t), n->left->left); - } else { // non-method call to method - if(!n->list) - fatal("non-method call to method without first arg: %+N", n); - if(t != T) - as = nod(OAS, tinlvar(t), n->list->n); - } - + if(!n->left->left) + fatal("method call without receiver: %+N", n); + if(t == T) + fatal("method call unknown receiver type: %+N", n); + as = nod(OAS, tinlvar(t), n->left->left); if(as != N) { typecheck(&as, Etop); ninit = list(ninit, as); } } + // check if inlined function is variadic. + variadic = 0; + varargtype = T; + varargcount = 0; + for(t=fn->type->type->down->down->type; t; t=t->down) { + if(t->isddd) { + variadic = 1; + varargtype = t->type; + } + } + // but if argument is dotted too forget about variadicity. + if(variadic && isddd) + variadic = 0; + + // check if argument is actually a returned tuple from call. + multiret = 0; + if(n->list && !n->list->next) { + switch(n->list->n->op) { + case OCALL: + case OCALLFUNC: + case OCALLINTER: + case OCALLMETH: + if(n->list->n->left->type->outtuple > 1) + multiret = n->list->n->left->type->outtuple-1; + } + } + + if(variadic) { + varargcount = count(n->list) + multiret; + if(n->left->op != ODOTMETH) + varargcount -= fn->type->thistuple; + varargcount -= fn->type->intuple - 1; + } + + // assign arguments to the parameters' temp names as = nod(OAS2, N, N); - if(fn->type->intuple > 1 && n->list && !n->list->next) { - // TODO check that n->list->n is a call? - // TODO: non-method call to T.meth(f()) where f returns t, args... - as->rlist = n->list; - for(t = getinargx(fn->type)->type; t; t=t->down) - as->list = list(as->list, tinlvar(t)); - } else { - ll = n->list; - if(fn->type->thistuple && n->left->op != ODOTMETH) // non method call to method - ll=ll->next; // was handled above in if(thistuple) + as->rlist = n->list; + ll = n->list; + + // TODO: if len(nlist) == 1 but multiple args, check that n->list->n is a call? + if(fn->type->thistuple && n->left->op != ODOTMETH) { + // non-method call to method + if(!n->list) + fatal("non-method call to method without first arg: %+N", n); + // append receiver inlvar to LHS. + t = getthisx(fn->type)->type; + if(t != T && t->nname != N && !isblank(t->nname) && !t->nname->inlvar) + fatal("missing inlvar for %N\n", t->nname); + if(t == T) + fatal("method call unknown receiver type: %+N", n); + as->list = list(as->list, tinlvar(t)); + ll = ll->next; // track argument count. + } - for(t = getinargx(fn->type)->type; t && ll; t=t->down) { + // append ordinary arguments to LHS. + chkargcount = n->list && n->list->next; + vararg = N; // the slice argument to a variadic call + varargs = nil; // the list of LHS names to put in vararg. + if(!chkargcount) { + // 0 or 1 expression on RHS. + for(t = getinargx(fn->type)->type; t; t=t->down) { + if(variadic && t->isddd) { + vararg = tinlvar(t); + for(i=0; i<varargcount && ll; i++) { + m = argvar(varargtype, i); + varargs = list(varargs, m); + as->list = list(as->list, m); + } + break; + } + as->list = list(as->list, tinlvar(t)); + } + } else { + // match arguments except final variadic (unless the call is dotted itself) + for(t = getinargx(fn->type)->type; t;) { + if(!ll) + break; + if(variadic && t->isddd) + break; as->list = list(as->list, tinlvar(t)); - as->rlist = list(as->rlist, ll->n); + t=t->down; ll=ll->next; } + // match varargcount arguments with variadic parameters. + if(variadic && t && t->isddd) { + vararg = tinlvar(t); + for(i=0; i<varargcount && ll; i++) { + m = argvar(varargtype, i); + varargs = list(varargs, m); + as->list = list(as->list, m); + ll=ll->next; + } + if(i==varargcount) + t=t->down; + } if(ll || t) fatal("arg count mismatch: %#T vs %,H\n", getinargx(fn->type), n->list); } @@ -632,6 +705,25 @@ mkinlcall1(Node **np, Node *fn) ninit = list(ninit, as); } + // turn the variadic args into a slice. + if(variadic) { + as = nod(OAS, vararg, N); + if(!varargcount) { + as->right = nodnil(); + as->right->type = varargtype; + } else { + vararrtype = typ(TARRAY); + vararrtype->type = varargtype->type; + vararrtype->bound = varargcount; + + as->right = nod(OCOMPLIT, N, typenod(varargtype)); + as->right->list = varargs; + as->right = nod(OSLICE, as->right, nod(OKEY, N, N)); + } + typecheck(&as, Etop); + ninit = list(ninit, as); + } + // zero the outparams for(ll = inlretvars; ll; ll=ll->next) { as = nod(OAS, ll->n, N); @@ -640,12 +732,14 @@ mkinlcall1(Node **np, Node *fn) } inlretlabel = newlabel(); + inlgen++; body = inlsubstlist(fn->inl); body = list(body, nod(OGOTO, inlretlabel, N)); // avoid 'not used' when function doesnt have return body = list(body, nod(OLABEL, inlretlabel, N)); typechecklist(body, Etop); +//dumplist("ninit post", ninit); call = nod(OINLCALL, N, N); call->ninit = ninit; @@ -655,6 +749,7 @@ mkinlcall1(Node **np, Node *fn) call->typecheck = 1; setlno(call, n->lineno); +//dumplist("call body", body); *np = call; @@ -705,7 +800,24 @@ retvar(Type *t, int i) { Node *n; - snprint(namebuf, sizeof(namebuf), ".r%d", i); + snprint(namebuf, sizeof(namebuf), "~r%d", i); + n = newname(lookup(namebuf)); + n->type = t->type; + n->class = PAUTO; + n->used = 1; + n->curfn = curfn; // the calling function, not the called one + curfn->dcl = list(curfn->dcl, n); + return n; +} + +// Synthesize a variable to store the inlined function's arguments +// when they come from a multiple return call. +static Node* +argvar(Type *t, int i) +{ + Node *n; + + snprint(namebuf, sizeof(namebuf), "~arg%d", i); n = newname(lookup(namebuf)); n->type = t->type; n->class = PAUTO; @@ -746,6 +858,7 @@ inlsubstlist(NodeList *ll) static Node* inlsubst(Node *n) { + char *p; Node *m, *as; NodeList *ll; @@ -788,6 +901,16 @@ inlsubst(Node *n) typecheck(&m, Etop); // dump("Return after substitution", m); return m; + + case OGOTO: + case OLABEL: + m = nod(OXXX, N, N); + *m = *n; + m->ninit = nil; + p = smprint("%s·%d", n->left->sym->name, inlgen); + m->left = newname(lookup(p)); + free(p); + return m; } diff --git a/src/cmd/gc/lex.c b/src/cmd/gc/lex.c index 624dfb0b4..68ae6864d 100644 --- a/src/cmd/gc/lex.c +++ b/src/cmd/gc/lex.c @@ -30,6 +30,8 @@ static void addidir(char*); static int getlinepragma(void); static char *goos, *goarch, *goroot; +#define BOM 0xFEFF + // Compiler experiments. // These are controlled by the GOEXPERIMENT environment // variable recorded when the compiler is built. @@ -38,6 +40,7 @@ static struct { int *val; } exper[] = { // {"rune32", &rune32}, + {"fieldtrack", &fieldtrack_enabled}, {nil, nil}, }; @@ -96,7 +99,7 @@ yy_isdigit(int c) static int yy_isspace(int c) { - return c >= 0 && c <= 0xFF && isspace(c); + return c == ' ' || c == '\t' || c == '\n' || c == '\r'; } static int @@ -130,42 +133,8 @@ enum void usage(void) { - print("gc: usage: %cg [flags] file.go...\n", thechar); - print("flags:\n"); - // -A allow use of "any" type, for bootstrapping - // -B disable bounds checking - // -E print imported declarations - // -K warn when lineno is zero - // -M print arguments to gmove - // -P print peephole diagnostics - // -R print optimizer diagnostics - // -g print code generation diagnostics - // -i print line history - // -j print variables to be initialized at runtime - // -r print generated helper functions - // -s print redundant types in composite literals - // -v print more information with -P or -R - // -y print declarations in cannedimports (used with -d) - // -% print non-static initializers - // -+ indicate that the runtime is being compiled - print(" -D PATH interpret local imports relative to this import path\n"); - print(" -I DIR search for packages in DIR\n"); - print(" -L show full path in file:line prints\n"); - print(" -N disable optimizations\n"); - print(" -S print the assembly language\n"); - print(" -V print the compiler version\n"); - print(" -W print the parse tree after typing\n"); - print(" -d print declarations\n"); - print(" -e no limit on number of errors printed\n"); - print(" -f print stack frame structure\n"); - print(" -h panic on an error\n"); - print(" -l disable inlining\n"); - print(" -m print optimization decisions\n"); - print(" -o file specify output file\n"); - print(" -p assumed import path for this code\n"); - print(" -u disable package unsafe\n"); - print(" -w print type checking details\n"); - print(" -x print lex tokens\n"); + print("usage: %cg [options] file.go...\n", thechar); + flagprint(1); exits("usage"); } @@ -183,11 +152,23 @@ fault(int s) fatal("fault"); } +void +doversion(void) +{ + char *p; + + p = expstring(); + if(strcmp(p, "X:none") == 0) + p = ""; + print("%cg version %s%s%s\n", thechar, getgoversion(), *p ? " " : "", p); + exits(0); +} + int main(int argc, char *argv[]) { - int i, c; - NodeList *l, *batch; + int i; + NodeList *l; char *p; #ifdef SIGBUS @@ -197,25 +178,41 @@ main(int argc, char *argv[]) localpkg = mkpkg(strlit("")); localpkg->prefix = "\"\""; - + + // pseudo-package, for scoping builtinpkg = mkpkg(strlit("go.builtin")); + // pseudo-package, accessed by import "unsafe" + unsafepkg = mkpkg(strlit("unsafe")); + unsafepkg->name = "unsafe"; + + // real package, referred to by generated runtime calls + runtimepkg = mkpkg(strlit("runtime")); + runtimepkg->name = "runtime"; + + // pseudo-packages used in symbol tables gostringpkg = mkpkg(strlit("go.string")); gostringpkg->name = "go.string"; gostringpkg->prefix = "go.string"; // not go%2estring - runtimepkg = mkpkg(strlit("runtime")); - runtimepkg->name = "runtime"; + itabpkg = mkpkg(strlit("go.itab")); + itabpkg->name = "go.itab"; + itabpkg->prefix = "go.itab"; // not go%2eitab - typepkg = mkpkg(strlit("type")); - typepkg->name = "type"; + weaktypepkg = mkpkg(strlit("go.weak.type")); + weaktypepkg->name = "go.weak.type"; + weaktypepkg->prefix = "go.weak.type"; // not go%2eweak%2etype + + typelinkpkg = mkpkg(strlit("go.typelink")); + typelinkpkg->name = "go.typelink"; + typelinkpkg->prefix = "go.typelink"; // not go%2etypelink - weaktypepkg = mkpkg(strlit("weak.type")); - weaktypepkg->name = "weak.type"; - weaktypepkg->prefix = "weak.type"; // not weak%2etype + trackpkg = mkpkg(strlit("go.track")); + trackpkg->name = "go.track"; + trackpkg->prefix = "go.track"; // not go%2etrack - unsafepkg = mkpkg(strlit("unsafe")); - unsafepkg->name = "unsafe"; + typepkg = mkpkg(strlit("type")); + typepkg->name = "type"; goroot = getgoroot(); goos = getgoos(); @@ -224,41 +221,55 @@ main(int argc, char *argv[]) setexp(); outfile = nil; - ARGBEGIN { - default: - c = ARGC(); - if(c >= 0 && c < sizeof(debug)) - debug[c]++; - break; - - case 'o': - outfile = EARGF(usage()); - break; - - case 'p': - myimportpath = EARGF(usage()); - break; + flagcount("+", "compiling runtime", &compiling_runtime); + flagcount("%", "debug non-static initializers", &debug['%']); + flagcount("A", "for bootstrapping, allow 'any' type", &debug['A']); + flagcount("B", "disable bounds checking", &debug['B']); + flagstr("D", "path: set relative path for local imports", &localimport); + flagcount("E", "debug symbol export", &debug['E']); + flagfn1("I", "dir: add dir to import search path", addidir); + flagcount("K", "debug missing line numbers", &debug['K']); + flagcount("L", "use full (long) path in error messages", &debug['L']); + flagcount("M", "debug move generation", &debug['M']); + flagcount("N", "disable optimizations", &debug['N']); + flagcount("P", "debug peephole optimizer", &debug['P']); + flagcount("R", "debug register optimizer", &debug['R']); + flagcount("S", "print assembly listing", &debug['S']); + flagfn0("V", "print compiler version", doversion); + flagcount("W", "debug parse tree after type checking", &debug['W']); + flagcount("complete", "compiling complete package (no C or assembly)", &pure_go); + flagcount("d", "debug declarations", &debug['d']); + flagcount("e", "no limit on number of errors reported", &debug['e']); + flagcount("f", "debug stack frames", &debug['f']); + flagcount("g", "debug code generation", &debug['g']); + flagcount("h", "halt on error", &debug['h']); + flagcount("i", "debug line number stack", &debug['i']); + flagcount("j", "debug runtime-initialized variables", &debug['j']); + flagcount("l", "disable inlining", &debug['l']); + flagcount("m", "print optimization decisions", &debug['m']); + flagstr("o", "obj: set output file", &outfile); + flagstr("p", "path: set expected package import path", &myimportpath); + flagcount("r", "debug generated wrappers", &debug['r']); + flagcount("race", "enable race detector", &flag_race); + flagcount("s", "warn about composite literals that can be simplified", &debug['s']); + flagcount("u", "reject unsafe code", &safemode); + flagcount("v", "increase debug verbosity", &debug['v']); + flagcount("w", "debug type checking", &debug['w']); + flagcount("x", "debug lexer", &debug['x']); + flagcount("y", "debug declarations in canned imports (with -d)", &debug['y']); + if(thechar == '6') + flagcount("largemodel", "generate code that assumes a large memory model", &flag_largemodel); + + flagparse(&argc, &argv, usage); - case 'u': - safemode = 1; - break; + if(argc < 1) + usage(); - case 'D': - localimport = EARGF(usage()); - break; + if(flag_race) { + racepkg = mkpkg(strlit("runtime/race")); + racepkg->name = "race"; + } - case 'I': - addidir(EARGF(usage())); - break; - - case 'V': - p = expstring(); - if(strcmp(p, "X:none") == 0) - p = ""; - print("%cg version %s%s%s\n", thechar, getgoversion(), *p ? " " : "", p); - exits(0); - } ARGEND - // enable inlining. for now: // default: inlining on. (debug['l'] == 1) // -l: inlining off (debug['l'] == 0) @@ -266,11 +277,15 @@ main(int argc, char *argv[]) if(debug['l'] <= 1) debug['l'] = 1 - debug['l']; - if(argc < 1) - usage(); - - // special flag to detect compilation of package runtime - compiling_runtime = debug['+']; + if(thechar == '8') { + p = getgo386(); + if(strcmp(p, "387") == 0) + use_sse = 0; + else if(strcmp(p, "sse2") == 0) + use_sse = 1; + else + sysfatal("unsupported setting GO386=%s", p); + } pathname = mal(1000); if(getwd(pathname, 999) == 0) @@ -315,6 +330,10 @@ main(int argc, char *argv[]) curio.peekc1 = 0; curio.nlsemi = 0; + // Skip initial BOM if present. + if(Bgetrune(curio.bin) != BOM) + Bungetrune(curio.bin); + block = 1; iota = -1000000; @@ -335,6 +354,7 @@ main(int argc, char *argv[]) frame(1); // Process top-level declarations in phases. + // Phase 1: const, type, and names and types of funcs. // This will gather all the information about types // and methods but doesn't depend on any of it. @@ -367,7 +387,7 @@ main(int argc, char *argv[]) errorexit(); // Phase 4: Inlining - if (debug['l'] > 1) { + if(debug['l'] > 1) { // Typecheck imported function bodies if debug['l'] > 1, // otherwise lazily when used or re-exported. for(l=importlist; l; l=l->next) @@ -380,7 +400,7 @@ main(int argc, char *argv[]) errorexit(); } - if (debug['l']) { + if(debug['l']) { // Find functions that can be inlined and clone them before walk expands them. for(l=xtop; l; l=l->next) if(l->n->op == ODCLFUNC) @@ -392,7 +412,7 @@ main(int argc, char *argv[]) inlcalls(l->n); } - // Phase 5: escape analysis. + // Phase 5: Escape analysis. if(!debug['N']) escapes(xtop); @@ -404,21 +424,7 @@ main(int argc, char *argv[]) if(nsavederrors+nerrors == 0) fninit(xtop); - // Phase 6b: Compile all closures. - // Can generate more closures, so run in batches. - while(closures) { - batch = closures; - closures = nil; - if(debug['l']) - for(l=batch; l; l=l->next) - inlcalls(l->n); - if(!debug['N']) - escapes(batch); - for(l=batch; l; l=l->next) - funccompile(l->n, 1); - } - - // Phase 7: check external declarations. + // Phase 7: Check external declarations. for(l=externdcl; l; l=l->next) if(l->n->op == ONAME) typecheck(&l->n, Erv); @@ -483,7 +489,7 @@ skiptopkgdef(Biobuf *b) if(memcmp(p, "!<arch>\n", 8) != 0) return 0; /* symbol table is first; skip it */ - sz = arsize(b, "__.SYMDEF"); + sz = arsize(b, "__.GOSYMDEF"); if(sz < 0) return 0; Bseek(b, sz, 1); @@ -533,7 +539,7 @@ static int findpkg(Strlit *name) { Idir *p; - char *q; + char *q, *race; if(islocalname(name)) { if(safemode) @@ -571,10 +577,13 @@ findpkg(Strlit *name) return 1; } if(goroot != nil) { - snprint(namebuf, sizeof(namebuf), "%s/pkg/%s_%s/%Z.a", goroot, goos, goarch, name); + race = ""; + if(flag_race) + race = "_race"; + snprint(namebuf, sizeof(namebuf), "%s/pkg/%s_%s%s/%Z.a", goroot, goos, goarch, race, name); if(access(namebuf, 0) >= 0) return 1; - snprint(namebuf, sizeof(namebuf), "%s/pkg/%s_%s/%Z.%c", goroot, goos, goarch, name, thechar); + snprint(namebuf, sizeof(namebuf), "%s/pkg/%s_%s%s/%Z.%c", goroot, goos, goarch, race, name, thechar); if(access(namebuf, 0) >= 0) return 1; } @@ -659,6 +668,11 @@ importfile(Val *f, int line) strcat(cleanbuf, path->s); cleanname(cleanbuf); path = strlit(cleanbuf); + + if(isbadimport(path)) { + fakeimport(); + return; + } } if(!findpkg(path)) { @@ -667,6 +681,16 @@ importfile(Val *f, int line) } importpkg = mkpkg(path); + // If we already saw that package, feed a dummy statement + // to the lexer to avoid parsing export data twice. + if(importpkg->imported) { + file = strdup(namebuf); + p = smprint("package %s\n$$\n", importpkg->name); + cannedimports(file, p); + return; + } + importpkg->imported = 1; + imp = Bopen(namebuf, OREAD); if(imp == nil) { yyerror("can't open import: \"%Z\": %r", f->u.sval); @@ -767,12 +791,8 @@ static int isfrog(int c) { // complain about possibly invisible control characters - if(c < 0) - return 1; if(c < ' ') { - if(c == '\n' || c== '\r' || c == '\t') // good white space - return 0; - return 1; + return !yy_isspace(c); // exclude good white space } if(0x7f <= c && c <= 0xa0) // DEL, unicode block including unbreakable space. return 1; @@ -982,6 +1002,7 @@ l0: c1 = getc(); if(c1 == '=') { c = LCOLAS; + yylval.i = lexlineno; goto lx; } break; @@ -1145,6 +1166,11 @@ l0: case '[': if(loophack || lstk != nil) { h = malloc(sizeof *h); + if(h == nil) { + flusherrors(); + yyerror("out of memory"); + errorexit(); + } h->v = loophack; h->next = lstk; lstk = h; @@ -1208,7 +1234,7 @@ talph: rune = getr(); // 0xb7 · is used for internal names if(!isalpharune(rune) && !isdigitrune(rune) && (importpkg == nil || rune != 0xb7)) - yyerror("invalid identifier character 0x%ux", rune); + yyerror("invalid identifier character U+%04x", rune); cp += runetochar(cp, &rune); } else if(!yy_isalnum(c) && c != '_') break; @@ -1270,12 +1296,14 @@ tnum: continue; if(cp == lexbuf+2) yyerror("malformed hex constant"); + if(c == 'p') + goto caseep; goto ncu; } } if(c == 'p') // 0p begins floating point zero - goto casep; + goto caseep; c1 = 0; for(;;) { @@ -1293,7 +1321,7 @@ tnum: if(c == '.') goto casedot; if(c == 'e' || c == 'E') - goto casee; + goto caseep; if(c == 'i') goto casei; if(c1) @@ -1303,10 +1331,8 @@ tnum: dc: if(c == '.') goto casedot; - if(c == 'e' || c == 'E') - goto casee; - if(c == 'p' || c == 'P') - goto casep; + if(c == 'e' || c == 'E' || c == 'p' || c == 'P') + goto caseep; if(c == 'i') goto casei; @@ -1342,29 +1368,8 @@ casedot: if(c != 'e' && c != 'E') goto caseout; -casee: - *cp++ = 'e'; - c = getc(); - if(c == '+' || c == '-') { - *cp++ = c; - c = getc(); - } - if(!yy_isdigit(c)) - yyerror("malformed fp constant exponent"); - while(yy_isdigit(c)) { - if(cp+10 >= ep) { - yyerror("identifier too long"); - errorexit(); - } - *cp++ = c; - c = getc(); - } - if(c == 'i') - goto casei; - goto caseout; - -casep: - *cp++ = 'p'; +caseep: + *cp++ = c; c = getc(); if(c == '+' || c == '-') { *cp++ = c; @@ -1430,7 +1435,12 @@ getlinepragma(void) char *cp, *ep, *linep; Hist *h; - for(i=0; i<5; i++) { + c = getr(); + if(c == 'g') + goto go; + if(c != 'l') + goto out; + for(i=1; i<5; i++) { c = getr(); if(c != "line "[i]) goto out; @@ -1478,7 +1488,35 @@ getlinepragma(void) } } linehist(strdup(lexbuf), n, 0); + goto out; + +go: + cp = lexbuf; + ep = lexbuf+sizeof(lexbuf)-5; + *cp++ = 'g'; // already read + for(;;) { + c = getr(); + if(c == EOF || c >= Runeself) + goto out; + if(c == '\n') + break; + if(cp < ep) + *cp++ = c; + } + *cp = 0; + ep = strchr(lexbuf, ' '); + if(ep != nil) + *ep = 0; + if(strcmp(lexbuf, "go:nointerface") == 0 && fieldtrack_enabled) { + nointerface = 1; + goto out; + } + if(strcmp(lexbuf, "go:noescape") == 0) { + noescape = 1; + goto out; + } + out: return c; } @@ -1524,24 +1562,35 @@ yylex(void) static int getc(void) { - int c; + int c, c1, c2; c = curio.peekc; if(c != 0) { curio.peekc = curio.peekc1; curio.peekc1 = 0; - if(c == '\n' && pushedio.bin == nil) - lexlineno++; - return c; + goto check; } if(curio.bin == nil) { c = *curio.cp & 0xff; if(c != 0) curio.cp++; - } else + } else { + loop: c = Bgetc(curio.bin); + if(c == 0xef) { + c1 = Bgetc(curio.bin); + c2 = Bgetc(curio.bin); + if(c1 == 0xbb && c2 == 0xbf) { + yyerrorl(lexlineno, "Unicode (UTF-8) BOM in middle of file"); + goto loop; + } + Bungetc(curio.bin); + Bungetc(curio.bin); + } + } +check: switch(c) { case 0: if(curio.bin != nil) { @@ -1820,16 +1869,16 @@ lexinit(void) if(etype != Txxx) { if(etype < 0 || etype >= nelem(types)) fatal("lexinit: %s bad etype", s->name); + s1 = pkglookup(syms[i].name, builtinpkg); t = types[etype]; if(t == T) { t = typ(etype); - t->sym = s; + t->sym = s1; if(etype != TANY && etype != TSTRING) dowidth(t); types[etype] = t; } - s1 = pkglookup(syms[i].name, builtinpkg); s1->lexical = LNAME; s1->def = typenod(t); continue; @@ -1959,8 +2008,10 @@ lexfini(void) s->lexical = lex; etype = syms[i].etype; - if(etype != Txxx && (etype != TANY || debug['A']) && s->def == N) + if(etype != Txxx && (etype != TANY || debug['A']) && s->def == N) { s->def = typenod(types[etype]); + s->origpkg = builtinpkg; + } etype = syms[i].op; if(etype != OXXX && s->def == N) { @@ -1968,54 +2019,68 @@ lexfini(void) s->def->sym = s; s->def->etype = etype; s->def->builtin = 1; + s->origpkg = builtinpkg; } } + // backend-specific builtin types (e.g. int). for(i=0; typedefs[i].name; i++) { s = lookup(typedefs[i].name); - if(s->def == N) + if(s->def == N) { s->def = typenod(types[typedefs[i].etype]); + s->origpkg = builtinpkg; + } } // there's only so much table-driven we can handle. // these are special cases. s = lookup("byte"); - if(s->def == N) + if(s->def == N) { s->def = typenod(bytetype); - + s->origpkg = builtinpkg; + } + s = lookup("error"); - if(s->def == N) + if(s->def == N) { s->def = typenod(errortype); + s->origpkg = builtinpkg; + } s = lookup("rune"); - if(s->def == N) + if(s->def == N) { s->def = typenod(runetype); + s->origpkg = builtinpkg; + } s = lookup("nil"); if(s->def == N) { v.ctype = CTNIL; s->def = nodlit(v); s->def->sym = s; + s->origpkg = builtinpkg; } - + s = lookup("iota"); if(s->def == N) { s->def = nod(OIOTA, N, N); s->def->sym = s; + s->origpkg = builtinpkg; } s = lookup("true"); if(s->def == N) { s->def = nodbool(1); s->def->sym = s; + s->origpkg = builtinpkg; } s = lookup("false"); if(s->def == N) { s->def = nodbool(0); s->def->sym = s; + s->origpkg = builtinpkg; } - + nodfp = nod(ONAME, N, N); nodfp->type = types[TINT32]; nodfp->xoffset = 0; @@ -2179,7 +2244,7 @@ mkpackage(char* pkgname) { Sym *s; int32 h; - char *p; + char *p, *q; if(localpkg->name == nil) { if(strcmp(pkgname, "_") == 0) @@ -2219,6 +2284,11 @@ mkpackage(char* pkgname) if(outfile == nil) { p = strrchr(infile, '/'); + if(windows) { + q = strrchr(infile, '\\'); + if(q > p) + p = q; + } if(p == nil) p = infile; else diff --git a/src/cmd/gc/mparith1.c b/src/cmd/gc/mparith1.c index 33fa90e2e..e25044a8b 100644 --- a/src/cmd/gc/mparith1.c +++ b/src/cmd/gc/mparith1.c @@ -43,10 +43,10 @@ mpcmpfixfix(Mpint *a, Mpint *b) int mpcmpfixc(Mpint *b, vlong c) { - Mpint a; + Mpint c1; - mpmovecfix(&a, c); - return mpcmpfixfix(&a, b); + mpmovecfix(&c1, c); + return mpcmpfixfix(b, &c1); } int @@ -232,16 +232,78 @@ mppow10flt(Mpflt *a, int p) mpmulcflt(a, 10); } +static void +mphextofix(Mpint *a, char *s, int n) +{ + char *hexdigitp, *end, c; + long d; + int bit; + + while(*s == '0') { + s++; + n--; + } + + // overflow + if(4*n > Mpscale*Mpprec) { + a->ovf = 1; + return; + } + + end = s+n-1; + for(hexdigitp=end; hexdigitp>=s; hexdigitp--) { + c = *hexdigitp; + if(c >= '0' && c <= '9') + d = c-'0'; + else if(c >= 'A' && c <= 'F') + d = c-'A'+10; + else + d = c-'a'+10; + + bit = 4*(end - hexdigitp); + while(d > 0) { + if(d & 1) + a->a[bit/Mpscale] |= (long)1 << (bit%Mpscale); + bit++; + d = d >> 1; + } + } +} + // // floating point input -// required syntax is [+-]d*[.]d*[e[+-]d*] +// required syntax is [+-]d*[.]d*[e[+-]d*] or [+-]0xH*[e[+-]d*] // void mpatoflt(Mpflt *a, char *as) { Mpflt b; - int dp, c, f, ef, ex, eb; - char *s; + int dp, c, f, ef, ex, eb, base; + char *s, *start; + + while(*as == ' ' || *as == '\t') + as++; + + /* determine base */ + s = as; + base = -1; + while(base == -1) { + switch(*s++) { + case '-': + case '+': + break; + + case '0': + if(*s == 'x') + base = 16; + else + base = 10; + break; + + default: + base = 10; + } + } s = as; dp = 0; /* digits after decimal point */ @@ -250,6 +312,37 @@ mpatoflt(Mpflt *a, char *as) eb = 0; /* binary point */ mpmovecflt(a, 0.0); + if(base == 16) { + start = nil; + for(;;) { + c = *s; + if(c == '-') { + f = 1; + s++; + } + else if(c == '+') { + s++; + } + else if(c == '0' && s[1] == 'x') { + s += 2; + start = s; + } + else if((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')) { + s++; + } + else { + break; + } + } + if(start == nil) + goto bad; + + mphextofix(&a->val, start, s-start); + if(a->val.ovf) + goto bad; + a->exp = 0; + mpnorm(a); + } for(;;) { switch(c = *s++) { default: @@ -259,11 +352,13 @@ mpatoflt(Mpflt *a, char *as) f = 1; case ' ': - case '\t': - case '+': + case '\t': + case '+': continue; case '.': + if(base == 16) + goto bad; dp = 1; continue; @@ -355,7 +450,7 @@ void mpatofix(Mpint *a, char *as) { int c, f; - char *s; + char *s, *s0; s = as; f = 0; @@ -402,28 +497,19 @@ oct: goto out; hex: - c = *s++; + s0 = s; + c = *s; while(c) { - if(c >= '0' && c <= '9') { - mpmulcfix(a, 16); - mpaddcfix(a, c-'0'); - c = *s++; - continue; - } - if(c >= 'a' && c <= 'f') { - mpmulcfix(a, 16); - mpaddcfix(a, c+10-'a'); - c = *s++; - continue; - } - if(c >= 'A' && c <= 'F') { - mpmulcfix(a, 16); - mpaddcfix(a, c+10-'A'); - c = *s++; + if((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')) { + s++; + c = *s; continue; } goto bad; } + mphextofix(a, s0, s-s0); + if(a->ovf) + goto bad; out: if(f) @@ -439,8 +525,8 @@ int Bconv(Fmt *fp) { char buf[500], *p; - Mpint *xval, q, r, ten; - int f; + Mpint *xval, q, r, ten, sixteen; + int f, digit; xval = va_arg(fp->args, Mpint*); mpmovefixfix(&q, xval); @@ -449,15 +535,33 @@ Bconv(Fmt *fp) f = 1; mpnegfix(&q); } - mpmovecfix(&ten, 10); p = &buf[sizeof(buf)]; *--p = 0; - for(;;) { - mpdivmodfixfix(&q, &r, &q, &ten); - *--p = mpgetfix(&r) + '0'; - if(mptestfix(&q) <= 0) - break; + if(fp->flags & FmtSharp) { + // Hexadecimal + mpmovecfix(&sixteen, 16); + for(;;) { + mpdivmodfixfix(&q, &r, &q, &sixteen); + digit = mpgetfix(&r); + if(digit < 10) + *--p = digit + '0'; + else + *--p = digit - 10 + 'A'; + if(mptestfix(&q) <= 0) + break; + } + *--p = 'x'; + *--p = '0'; + } else { + // Decimal + mpmovecfix(&ten, 10); + for(;;) { + mpdivmodfixfix(&q, &r, &q, &ten); + *--p = mpgetfix(&r) + '0'; + if(mptestfix(&q) <= 0) + break; + } } if(f) *--p = '-'; @@ -501,10 +605,10 @@ Fconv(Fmt *fp) } if(fv.exp >= 0) { - snprint(buf, sizeof(buf), "%Bp+%d", &fv.val, fv.exp); + snprint(buf, sizeof(buf), "%#Bp+%d", &fv.val, fv.exp); goto out; } - snprint(buf, sizeof(buf), "%Bp-%d", &fv.val, -fv.exp); + snprint(buf, sizeof(buf), "%#Bp-%d", &fv.val, -fv.exp); out: return fmtstrcpy(fp, buf); diff --git a/src/cmd/gc/obj.c b/src/cmd/gc/obj.c index e45b4e0d4..b87d35b7b 100644 --- a/src/cmd/gc/obj.c +++ b/src/cmd/gc/obj.c @@ -59,7 +59,13 @@ dumpglobls(void) continue; dowidth(n->type); - ggloblnod(n, n->type->width); + ggloblnod(n); + } + + for(l=funcsyms; l; l=l->next) { + n = l->n; + dsymptr(n->sym, 0, n->sym->def->shortname->sym, 0); + ggloblsym(n->sym, widthptr, 1, 1); } } @@ -302,8 +308,8 @@ stringsym(char *s, int len) off = 0; // string header - off = dsymptr(sym, off, sym, widthptr+4); - off = duint32(sym, off, len); + off = dsymptr(sym, off, sym, widthptr+widthint); + off = duintxx(sym, off, len, widthint); // string data for(n=0; n<len; n+=m) { @@ -314,7 +320,7 @@ stringsym(char *s, int len) } off = duint8(sym, off, 0); // terminating NUL for runtime off = (off+widthptr-1)&~(widthptr-1); // round to pointer alignment - ggloblsym(sym, off, 1); + ggloblsym(sym, off, 1, 1); return sym; } diff --git a/src/cmd/gc/order.c b/src/cmd/gc/order.c index 2cab5fb95..499a4e746 100644 --- a/src/cmd/gc/order.c +++ b/src/cmd/gc/order.c @@ -276,11 +276,11 @@ orderstmt(Node *n, NodeList **out) case OSELRECV2: orderexprinplace(&r->left); orderexprinplace(&r->ntest); - orderexpr(&r->right->left, out); + orderexpr(&r->right->left, &l->n->ninit); break; case OSEND: - orderexpr(&r->left, out); - orderexpr(&r->right, out); + orderexpr(&r->left, &l->n->ninit); + orderexpr(&r->right, &l->n->ninit); break; } } diff --git a/src/cmd/gc/pgen.c b/src/cmd/gc/pgen.c index f2b75d61b..df8903baf 100644 --- a/src/cmd/gc/pgen.c +++ b/src/cmd/gc/pgen.c @@ -14,11 +14,12 @@ compile(Node *fn) { Plist *pl; Node nod1, *n; - Prog *ptxt; + Prog *plocals, *ptxt, *p, *p1; int32 lno; Type *t; Iter save; vlong oldstksize; + NodeList *l; if(newproc == N) { newproc = sysfunc("newproc"); @@ -29,16 +30,19 @@ compile(Node *fn) throwreturn = sysfunc("throwreturn"); } - if(fn->nbody == nil) - return; + lno = setlineno(fn); + + if(fn->nbody == nil) { + if(pure_go || memcmp(fn->nname->sym->name, "init·", 6) == 0) + yyerror("missing function body", fn); + goto ret; + } saveerrors(); // set up domain for labels clearlabels(); - lno = setlineno(fn); - curfn = fn; dowidth(curfn->type); @@ -63,6 +67,10 @@ compile(Node *fn) walk(curfn); if(nerrors != 0) goto ret; + if(flag_race) + racewalk(curfn); + if(nerrors != 0) + goto ret; continpc = P; breakpc = P; @@ -76,15 +84,34 @@ compile(Node *fn) ptxt = gins(ATEXT, isblank(curfn->nname) ? N : curfn->nname, &nod1); if(fn->dupok) ptxt->TEXTFLAG = DUPOK; - afunclit(&ptxt->from); + afunclit(&ptxt->from, curfn->nname); ginit(); + + plocals = gins(ALOCALS, N, N); + + for(t=curfn->paramfld; t; t=t->down) + gtrack(tracksym(t->type)); + + for(l=fn->dcl; l; l=l->next) { + n = l->n; + if(n->op != ONAME) // might be OTYPE or OLITERAL + continue; + switch(n->class) { + case PAUTO: + case PPARAM: + case PPARAMOUT: + nodconst(&nod1, types[TUINTPTR], l->n->type->width); + p = gins(ATYPE, l->n, &nod1); + p->from.gotype = ngotype(l->n); + break; + } + } + genlist(curfn->enter); retpc = nil; if(hasdefer || curfn->exit) { - Prog *p1; - p1 = gjmp(nil); retpc = gjmp(nil); patch(p1, pc); @@ -111,6 +138,7 @@ compile(Node *fn) gclean(); if(nerrors != 0) goto ret; + pc->as = ARET; // overwrite AEND pc->lineno = lineno; @@ -120,6 +148,10 @@ compile(Node *fn) oldstksize = stksize; allocauto(ptxt); + + plocals->to.type = D_CONST; + plocals->to.offset = stksize; + if(0) print("allocauto: %lld to %lld\n", oldstksize, (vlong)stksize); @@ -177,8 +209,10 @@ allocauto(Prog* ptxt) ll = curfn->dcl; n = ll->n; if (n->class == PAUTO && n->op == ONAME && !n->used) { + // No locals used at all curfn->dcl = nil; stksize = 0; + fixautoused(ptxt); return; } diff --git a/src/cmd/gc/racewalk.c b/src/cmd/gc/racewalk.c new file mode 100644 index 000000000..bae98ec1b --- /dev/null +++ b/src/cmd/gc/racewalk.c @@ -0,0 +1,579 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// The racewalk pass modifies the code tree for the function as follows: +// +// 1. It inserts a call to racefuncenter at the beginning of each function. +// 2. It inserts a call to racefuncexit at the end of each function. +// 3. It inserts a call to raceread before each memory read. +// 4. It inserts a call to racewrite before each memory write. +// +// The rewriting is not yet complete. Certain nodes are not rewritten +// but should be. + +#include <u.h> +#include <libc.h> +#include "go.h" + +// TODO(dvyukov): do not instrument initialization as writes: +// a := make([]int, 10) + +static void racewalklist(NodeList *l, NodeList **init); +static void racewalknode(Node **np, NodeList **init, int wr, int skip); +static int callinstr(Node **n, NodeList **init, int wr, int skip); +static Node* uintptraddr(Node *n); +static Node* basenod(Node *n); +static void foreach(Node *n, void(*f)(Node*, void*), void *c); +static void hascallspred(Node *n, void *c); +static Node* detachexpr(Node *n, NodeList **init); + +// Do not instrument the following packages at all, +// at best instrumentation would cause infinite recursion. +static const char *omit_pkgs[] = {"runtime", "runtime/race"}; +// Only insert racefuncenter/racefuncexit into the following packages. +// Memory accesses in the packages are either uninteresting or will cause false positives. +static const char *noinst_pkgs[] = {"sync", "sync/atomic"}; + +static int +ispkgin(const char **pkgs, int n) +{ + int i; + + if(myimportpath) { + for(i=0; i<n; i++) { + if(strcmp(myimportpath, pkgs[i]) == 0) + return 1; + } + } + return 0; +} + +void +racewalk(Node *fn) +{ + Node *nd; + Node *nodpc; + char s[1024]; + + if(ispkgin(omit_pkgs, nelem(omit_pkgs))) + return; + + if(!ispkgin(noinst_pkgs, nelem(noinst_pkgs))) { + racewalklist(fn->nbody, nil); + // nothing interesting for race detector in fn->enter + racewalklist(fn->exit, nil); + } + + // nodpc is the PC of the caller as extracted by + // getcallerpc. We use -widthptr(FP) for x86. + // BUG: this will not work on arm. + nodpc = nod(OXXX, nil, nil); + *nodpc = *nodfp; + nodpc->type = types[TUINTPTR]; + nodpc->xoffset = -widthptr; + nd = mkcall("racefuncenter", T, nil, nodpc); + fn->enter = concat(list1(nd), fn->enter); + nd = mkcall("racefuncexit", T, nil); + fn->exit = list(fn->exit, nd); + + if(debug['W']) { + snprint(s, sizeof(s), "after racewalk %S", fn->nname->sym); + dumplist(s, fn->nbody); + snprint(s, sizeof(s), "enter %S", fn->nname->sym); + dumplist(s, fn->enter); + snprint(s, sizeof(s), "exit %S", fn->nname->sym); + dumplist(s, fn->exit); + } +} + +static void +racewalklist(NodeList *l, NodeList **init) +{ + NodeList *instr; + + for(; l; l = l->next) { + instr = nil; + racewalknode(&l->n, &instr, 0, 0); + if(init == nil) + l->n->ninit = concat(l->n->ninit, instr); + else + *init = concat(*init, instr); + } +} + +// walkexpr and walkstmt combined +// walks the tree and adds calls to the +// instrumentation code to top-level (statement) nodes' init +static void +racewalknode(Node **np, NodeList **init, int wr, int skip) +{ + Node *n, *n1; + NodeList *l; + NodeList *fini; + + n = *np; + + if(n == N) + return; + + if(debug['w'] > 1) + dump("racewalk-before", n); + setlineno(n); + if(init == nil || init == &n->ninit) + fatal("racewalk: bad init list"); + + racewalklist(n->ninit, nil); + + switch(n->op) { + default: + fatal("racewalk: unknown node type %O", n->op); + + case OASOP: + case OAS: + case OAS2: + case OAS2DOTTYPE: + case OAS2RECV: + case OAS2FUNC: + case OAS2MAPR: + racewalknode(&n->left, init, 1, 0); + racewalknode(&n->right, init, 0, 0); + goto ret; + + case OCFUNC: + // can't matter + goto ret; + + case OBLOCK: + if(n->list == nil) + goto ret; + + switch(n->list->n->op) { + case OCALLFUNC: + case OCALLMETH: + case OCALLINTER: + // Blocks are used for multiple return function calls. + // x, y := f() becomes BLOCK{CALL f, AS x [SP+0], AS y [SP+n]} + // We don't want to instrument between the statements because it will + // smash the results. + racewalknode(&n->list->n, &n->ninit, 0, 0); + fini = nil; + racewalklist(n->list->next, &fini); + n->list = concat(n->list, fini); + break; + + default: + // Ordinary block, for loop initialization or inlined bodies. + racewalklist(n->list, nil); + break; + } + goto ret; + + case ODEFER: + racewalknode(&n->left, init, 0, 0); + goto ret; + + case OPROC: + racewalknode(&n->left, init, 0, 0); + goto ret; + + case OCALLINTER: + racewalknode(&n->left, init, 0, 0); + goto ret; + + case OCALLFUNC: + racewalknode(&n->left, init, 0, 0); + goto ret; + + case OSWITCH: + if(n->ntest->op == OTYPESW) + // TODO(dvyukov): the expression can contain calls or reads. + return; + goto ret; + + case ONOT: + case OMINUS: + case OPLUS: + case OREAL: + case OIMAG: + racewalknode(&n->left, init, wr, 0); + goto ret; + + case ODOTINTER: + racewalknode(&n->left, init, 0, 0); + goto ret; + + case ODOT: + racewalknode(&n->left, init, 0, 1); + callinstr(&n, init, wr, skip); + goto ret; + + case ODOTPTR: // dst = (*x).f with implicit *; otherwise it's ODOT+OIND + racewalknode(&n->left, init, 0, 0); + callinstr(&n, init, wr, skip); + goto ret; + + case OIND: // *p + racewalknode(&n->left, init, 0, 0); + callinstr(&n, init, wr, skip); + goto ret; + + case OLEN: + case OCAP: + racewalknode(&n->left, init, 0, 0); + if(istype(n->left->type, TMAP)) { + // crashes on len(m[0]) or len(f()) + SET(n1); + USED(n1); + /* + n1 = nod(OADDR, n->left, N); + n1 = conv(n1, types[TUNSAFEPTR]); + n1 = conv(n1, ptrto(ptrto(types[TINT8]))); + n1 = nod(OIND, n1, N); + n1 = nod(OIND, n1, N); + typecheck(&n1, Erv); + callinstr(&n1, init, 0, skip); + */ + } + goto ret; + + case OLSH: + case ORSH: + case OAND: + case OANDNOT: + case OOR: + case OXOR: + case OSUB: + case OMUL: + case OEQ: + case ONE: + case OLT: + case OLE: + case OGE: + case OGT: + case OADD: + case OCOMPLEX: + racewalknode(&n->left, init, wr, 0); + racewalknode(&n->right, init, wr, 0); + goto ret; + + case OANDAND: + case OOROR: + racewalknode(&n->left, init, wr, 0); + // It requires more complex tree transformation, + // because we don't know whether it will be executed or not. + //racewalknode(&n->right, init, wr, 0); + goto ret; + + case ONAME: + callinstr(&n, init, wr, skip); + goto ret; + + case OCONV: + racewalknode(&n->left, init, wr, 0); + goto ret; + + case OCONVNOP: + racewalknode(&n->left, init, wr, 0); + goto ret; + + case ODIV: + case OMOD: + // TODO(dvyukov): add a test for this + racewalknode(&n->left, init, wr, 0); + racewalknode(&n->right, init, wr, 0); + goto ret; + + case OINDEX: + if(!isfixedarray(n->left->type)) + racewalknode(&n->left, init, 0, 0); + else if(!islvalue(n->left)) { + // index of unaddressable array, like Map[k][i]. + racewalknode(&n->left, init, wr, 0); + racewalknode(&n->right, init, 0, 0); + goto ret; + } + racewalknode(&n->right, init, 0, 0); + if(n->left->type->etype != TSTRING) + callinstr(&n, init, wr, skip); + goto ret; + + case OSLICE: + case OSLICEARR: + // Seems to only lead to double instrumentation. + //racewalknode(&n->left, init, 0, 0); + goto ret; + + case OADDR: + racewalknode(&n->left, init, 0, 1); + goto ret; + + case OEFACE: + racewalknode(&n->left, init, 0, 0); + racewalknode(&n->right, init, 0, 0); + goto ret; + + // should not appear in AST by now + case OSEND: + case ORECV: + case OCLOSE: + case ONEW: + case OXCASE: + case OXFALL: + case OCASE: + case OPANIC: + case ORECOVER: + case OCONVIFACE: + yyerror("racewalk: %O must be lowered by now", n->op); + goto ret; + + // just do generic traversal + case OFOR: + case OIF: + case OCALLMETH: + case ORETURN: + case OSELECT: + case OEMPTY: + goto ret; + + // does not require instrumentation + case OINDEXMAP: // implemented in runtime + case OPRINT: // don't bother instrumenting it + case OPRINTN: // don't bother instrumenting it + case OPARAM: // it appears only in fn->exit to copy heap params back + goto ret; + + // unimplemented + case OCMPSTR: + case OADDSTR: + case OSLICESTR: + case OAPPEND: + case OCOPY: + case OMAKECHAN: + case OMAKEMAP: + case OMAKESLICE: + case ORUNESTR: + case OARRAYBYTESTR: + case OARRAYRUNESTR: + case OSTRARRAYBYTE: + case OSTRARRAYRUNE: + case OCMPIFACE: + case OARRAYLIT: + case OMAPLIT: + case OSTRUCTLIT: + case OCLOSURE: + case ODOTTYPE: + case ODOTTYPE2: + case OCALL: + case OBREAK: + case ODCL: + case OCONTINUE: + case OFALL: + case OGOTO: + case OLABEL: + case ODCLCONST: + case ODCLTYPE: + case OLITERAL: + case ORANGE: + case OTYPE: + case ONONAME: + case OINDREG: + case OCOM: + case ODOTMETH: + case OITAB: + case OEXTEND: + case OHMUL: + case OLROT: + case ORROTC: + goto ret; + } + +ret: + if(n->op != OBLOCK) // OBLOCK is handled above in a special way. + racewalklist(n->list, init); + l = nil; + racewalknode(&n->ntest, &l, 0, 0); + n->ninit = concat(n->ninit, l); + l = nil; + racewalknode(&n->nincr, &l, 0, 0); + n->ninit = concat(n->ninit, l); + racewalklist(n->nbody, nil); + racewalklist(n->nelse, nil); + racewalklist(n->rlist, nil); + + *np = n; +} + +static int +isartificial(Node *n) +{ + // compiler-emitted artificial things that we do not want to instrument, + // cant' possibly participate in a data race. + if(n->op == ONAME && n->sym != S && n->sym->name != nil) { + if(strcmp(n->sym->name, "_") == 0) + return 1; + // autotmp's are always local + if(strncmp(n->sym->name, "autotmp_", sizeof("autotmp_")-1) == 0) + return 1; + // statictmp's are read-only + if(strncmp(n->sym->name, "statictmp_", sizeof("statictmp_")-1) == 0) + return 1; + // go.itab is accessed only by the compiler and runtime (assume safe) + if(n->sym->pkg && n->sym->pkg->name && strcmp(n->sym->pkg->name, "go.itab") == 0) + return 1; + } + return 0; +} + +static int +callinstr(Node **np, NodeList **init, int wr, int skip) +{ + Node *f, *b, *n; + Type *t, *t1; + int class, res, hascalls; + + n = *np; + //print("callinstr for %+N [ %O ] etype=%E class=%d\n", + // n, n->op, n->type ? n->type->etype : -1, n->class); + + if(skip || n->type == T || n->type->etype >= TIDEAL) + return 0; + t = n->type; + if(isartificial(n)) + return 0; + if(t->etype == TSTRUCT) { + // PARAMs w/o PHEAP are not interesting. + if(n->class == PPARAM || n->class == PPARAMOUT) + return 0; + res = 0; + hascalls = 0; + foreach(n, hascallspred, &hascalls); + if(hascalls) { + n = detachexpr(n, init); + *np = n; + } + for(t1=t->type; t1; t1=t1->down) { + if(t1->sym && strcmp(t1->sym->name, "_")) { + n = treecopy(n); + f = nod(OXDOT, n, newname(t1->sym)); + f->type = t1; + if(f->type->etype == TFIELD) + f->type = f->type->type; + if(callinstr(&f, init, wr, 0)) { + typecheck(&f, Erv); + res = 1; + } + } + } + return res; + } + + b = basenod(n); + // it skips e.g. stores to ... parameter array + if(isartificial(b)) + return 0; + class = b->class; + // BUG: we _may_ want to instrument PAUTO sometimes + // e.g. if we've got a local variable/method receiver + // that has got a pointer inside. Whether it points to + // the heap or not is impossible to know at compile time + if((class&PHEAP) || class == PPARAMREF || class == PEXTERN + || b->type->etype == TARRAY || b->op == ODOTPTR || b->op == OIND || b->op == OXDOT) { + hascalls = 0; + foreach(n, hascallspred, &hascalls); + if(hascalls) { + n = detachexpr(n, init); + *np = n; + } + n = treecopy(n); + f = mkcall(wr ? "racewrite" : "raceread", T, init, uintptraddr(n)); + *init = list(*init, f); + return 1; + } + return 0; +} + +static Node* +uintptraddr(Node *n) +{ + Node *r; + + r = nod(OADDR, n, N); + r = conv(r, types[TUNSAFEPTR]); + r = conv(r, types[TUINTPTR]); + return r; +} + +static Node* +basenod(Node *n) +{ + for(;;) { + if(n->op == ODOT || n->op == OXDOT || n->op == OCONVNOP || n->op == OCONV || n->op == OPAREN) { + n = n->left; + continue; + } + if(n->op == OINDEX) { + n = n->left; + continue; + } + break; + } + return n; +} + +static Node* +detachexpr(Node *n, NodeList **init) +{ + Node *addr, *as, *ind, *l; + + addr = nod(OADDR, n, N); + l = temp(ptrto(n->type)); + as = nod(OAS, l, addr); + typecheck(&as, Etop); + walkexpr(&as, init); + *init = list(*init, as); + ind = nod(OIND, l, N); + typecheck(&ind, Erv); + walkexpr(&ind, init); + return ind; +} + +static void +foreachnode(Node *n, void(*f)(Node*, void*), void *c) +{ + if(n) + f(n, c); +} + +static void +foreachlist(NodeList *l, void(*f)(Node*, void*), void *c) +{ + for(; l; l = l->next) + foreachnode(l->n, f, c); +} + +static void +foreach(Node *n, void(*f)(Node*, void*), void *c) +{ + foreachlist(n->ninit, f, c); + foreachnode(n->left, f, c); + foreachnode(n->right, f, c); + foreachlist(n->list, f, c); + foreachnode(n->ntest, f, c); + foreachnode(n->nincr, f, c); + foreachlist(n->nbody, f, c); + foreachlist(n->nelse, f, c); + foreachlist(n->rlist, f, c); +} + +static void +hascallspred(Node *n, void *c) +{ + switch(n->op) { + case OCALL: + case OCALLFUNC: + case OCALLMETH: + case OCALLINTER: + (*(int*)c)++; + } +} diff --git a/src/cmd/gc/range.c b/src/cmd/gc/range.c index d301e4e4f..50c4617c0 100644 --- a/src/cmd/gc/range.c +++ b/src/cmd/gc/range.c @@ -72,6 +72,15 @@ typecheckrange(Node *n) if(n->list->next) v2 = n->list->next->n; + // this is not only a optimization but also a requirement in the spec. + // "if the second iteration variable is the blank identifier, the range + // clause is equivalent to the same clause with only the first variable + // present." + if(isblank(v2)) { + n->list = list1(v1); + v2 = N; + } + if(v1->defn == n) v1->type = t1; else if(v1->type != T && assignop(t1, v1->type, &why) == 0) @@ -145,7 +154,7 @@ walkrange(Node *n) if(v2) { hp = temp(ptrto(n->type->type)); tmp = nod(OINDEX, ha, nodintconst(0)); - tmp->etype = 1; // no bounds check + tmp->bounded = 1; init = list(init, nod(OAS, hp, nod(OADDR, tmp, N))); } diff --git a/src/cmd/gc/reflect.c b/src/cmd/gc/reflect.c index 62759bcba..b8eb79938 100644 --- a/src/cmd/gc/reflect.c +++ b/src/cmd/gc/reflect.c @@ -5,6 +5,7 @@ #include <u.h> #include <libc.h> #include "go.h" +#include "../../pkg/runtime/mgc0.h" /* * runtime interface and reflection data structures @@ -14,12 +15,13 @@ static NodeList* signatlist; static Sym* dtypesym(Type*); static Sym* weaktypesym(Type*); static Sym* dalgsym(Type*); +static Sym* dgcsym(Type*); static int sigcmp(Sig *a, Sig *b) { int i; - + i = strcmp(a->name, b->name); if(i != 0) return i; @@ -130,7 +132,12 @@ methodfunc(Type *f, Type *receiver) out = list(out, d); } - return functype(N, in, out); + t = functype(N, in, out); + if(f->nname) { + // Link to name of original method function. + t->nname = f->nname; + } + return t; } /* @@ -165,6 +172,8 @@ methods(Type *t) fatal("non-method on %T method %S %T\n", mt, f->sym, f); if (!getthisx(f->type)->type) fatal("receiver with no type on %T method %S %T\n", mt, f->sym, f); + if(f->nointerface) + continue; method = f->sym; if(method == nil) @@ -203,22 +212,26 @@ methods(Type *t) // but we can generate more efficient code // using genembedtramp if all that is necessary // is a pointer adjustment and a JMP. + compiling_wrappers = 1; if(isptr[it->etype] && isptr[this->etype] && f->embedded && !isifacemethod(f->type)) genembedtramp(it, f, a->isym, 1); else genwrapper(it, f, a->isym, 1); + compiling_wrappers = 0; } } if(!(a->tsym->flags & SymSiggen)) { a->tsym->flags |= SymSiggen; if(!eqtype(this, t)) { + compiling_wrappers = 1; if(isptr[t->etype] && isptr[this->etype] && f->embedded && !isifacemethod(f->type)) genembedtramp(t, f, a->tsym, 0); else genwrapper(t, f, a->tsym, 0); + compiling_wrappers = 0; } } } @@ -262,12 +275,12 @@ imethods(Type *t) else last->link = a; last = a; - + // Compiler can only refer to wrappers for // named interface types. if(t->sym == S) continue; - + // NOTE(rsc): Perhaps an oversight that // IfaceType.Method is not in the reflect data. // Generate the method body, so that compiled @@ -287,7 +300,7 @@ dimportpath(Pkg *p) static Pkg *gopkg; char *nam; Node *n; - + if(p->pathsym != S) return; @@ -303,9 +316,9 @@ dimportpath(Pkg *p) n->class = PEXTERN; n->xoffset = 0; p->pathsym = n->sym; - + gdatastring(n, p->path); - ggloblsym(n->sym, types[TSTRING]->width, 1); + ggloblsym(n->sym, types[TSTRING]->width, 1, 1); } static int @@ -319,7 +332,7 @@ dgopkgpath(Sym *s, int ot, Pkg *pkg) // that imports this one directly defines the symbol. if(pkg == localpkg) { static Sym *ns; - + if(ns == nil) ns = pkglookup("importpath.\"\".", mkpkg(strlit("go"))); return dsymptr(s, ot, ns, 0); @@ -343,7 +356,7 @@ dextratype(Sym *sym, int off, Type *t, int ptroff) m = methods(t); if(t->sym == nil && m == nil) return off; - + // fill in *extraType pointer in header dsymptr(sym, ptroff, sym, off); @@ -367,9 +380,9 @@ dextratype(Sym *sym, int off, Type *t, int ptroff) } // slice header - ot = dsymptr(s, ot, s, ot + widthptr + 2*4); - ot = duint32(s, ot, n); - ot = duint32(s, ot, n); + ot = dsymptr(s, ot, s, ot + widthptr + 2*widthint); + ot = duintxx(s, ot, n, widthint); + ot = duintxx(s, ot, n, widthint); // methods for(a=m; a; a=a->link) { @@ -419,7 +432,7 @@ enum { KindString, KindStruct, KindUnsafePointer, - + KindNoPointers = 1<<7, }; @@ -454,19 +467,6 @@ kinds[] = [TUNSAFEPTR] = KindUnsafePointer, }; -static Sym* -typestruct(Type *t) -{ - // We use a weak reference to the reflect type - // to avoid requiring package reflect in every binary. - // If package reflect is available, the interface{} holding - // a runtime type will contain a *reflect.commonType. - // Otherwise it will use a nil type word but still be usable - // by package runtime (because we always use the memory - // after the interface value, not the interface value itself). - return pkglookup("*reflect.commonType", weaktypepkg); -} - int haspointers(Type *t) { @@ -521,6 +521,9 @@ dcommontype(Sym *s, int ot, Type *t) Sym *sptr, *algsym; static Sym *algarray; char *p; + + if(ot != 0) + fatal("dcommontype %d", ot); sizeofAlg = 4*widthptr; if(algarray == nil) @@ -536,31 +539,34 @@ dcommontype(Sym *s, int ot, Type *t) else sptr = weaktypesym(ptrto(t)); - // empty interface pointing at this type. - // all the references that we emit are *interface{}; - // they point here. - ot = rnd(ot, widthptr); - ot = dsymptr(s, ot, typestruct(t), 0); - ot = dsymptr(s, ot, s, 2*widthptr); - // ../../pkg/reflect/type.go:/^type.commonType // actual type structure // type commonType struct { - // size uintptr; - // hash uint32; - // alg uint8; - // align uint8; - // fieldAlign uint8; - // kind uint8; - // string *string; - // *extraType; - // ptrToThis *Type + // size uintptr + // hash uint32 + // _ uint8 + // align uint8 + // fieldAlign uint8 + // kind uint8 + // alg unsafe.Pointer + // gc unsafe.Pointer + // string *string + // *extraType + // ptrToThis *Type // } ot = duintptr(s, ot, t->width); ot = duint32(s, ot, typehash(t)); ot = duint8(s, ot, 0); // unused + + // runtime (and common sense) expects alignment to be a power of two. + i = t->align; + if(i == 0) + i = 1; + if((i&(i-1)) != 0) + fatal("invalid alignment %d for %T", t->align, t); ot = duint8(s, ot, t->align); // align ot = duint8(s, ot, t->align); // fieldAlign + i = kinds[t->etype]; if(t->etype == TARRAY && t->bound < 0) i = KindSlice; @@ -571,11 +577,12 @@ dcommontype(Sym *s, int ot, Type *t) ot = dsymptr(s, ot, algarray, alg*sizeofAlg); else ot = dsymptr(s, ot, algsym, 0); + ot = dsymptr(s, ot, dgcsym(t), 0); // gc p = smprint("%-uT", t); //print("dcommontype: %s\n", p); ot = dgostringptr(s, ot, p); // string free(p); - + // skip pointer to extraType, // which follows the rest of this type structure. // caller will fill in if needed. @@ -600,6 +607,39 @@ typesym(Type *t) } Sym* +tracksym(Type *t) +{ + char *p; + Sym *s; + + p = smprint("%-T.%s", t->outer, t->sym->name); + s = pkglookup(p, trackpkg); + free(p); + return s; +} + +Sym* +typelinksym(Type *t) +{ + char *p; + Sym *s; + + // %-uT is what the generated Type's string field says. + // It uses (ambiguous) package names instead of import paths. + // %-T is the complete, unambiguous type name. + // We want the types to end up sorted by string field, + // so use that first in the name, and then add :%-T to + // disambiguate. The names are a little long but they are + // discarded by the linker and do not end up in the symbol + // table of the final binary. + p = smprint("%-uT/%-T", t, t); + s = pkglookup(p, typelinkpkg); + //print("typelinksym: %s -> %+S\n", p, s); + free(p); + return s; +} + +Sym* typesymprefix(char *prefix, Type *t) { char *p; @@ -612,8 +652,8 @@ typesymprefix(char *prefix, Type *t) return s; } -Node* -typename(Type *t) +Sym* +typenamesym(Type *t) { Sym *s; Node *n; @@ -634,7 +674,16 @@ typename(Type *t) signatlist = list(signatlist, typenod(t)); } + return s->def->sym; +} + +Node* +typename(Type *t) +{ + Sym *s; + Node *n; + s = typenamesym(t); n = nod(OADDR, s->def, N); n->type = ptrto(s->def->type); n->addable = 1; @@ -660,10 +709,16 @@ static Sym* dtypesym(Type *t) { int ot, xt, n, isddd, dupok; - Sym *s, *s1, *s2; + Sym *s, *s1, *s2, *slink; Sig *a, *m; Type *t1, *tbase, *t2; + // Replace byte, rune aliases with real type. + // They've been separate internally to make error messages + // better, but we have to merge them in the reflect tables. + if(t == bytetype || t == runetype) + t = types[t->etype]; + if(isideal(t)) fatal("dtypesym %T", t); @@ -680,7 +735,7 @@ dtypesym(Type *t) tbase = t->type; dupok = tbase->sym == S; - if(compiling_runtime && + if(compiling_runtime && (tbase == types[tbase->etype] || tbase == bytetype || tbase == runetype || @@ -751,13 +806,13 @@ ok: // two slice headers: in and out. ot = rnd(ot, widthptr); - ot = dsymptr(s, ot, s, ot+2*(widthptr+2*4)); + ot = dsymptr(s, ot, s, ot+2*(widthptr+2*widthint)); n = t->thistuple + t->intuple; - ot = duint32(s, ot, n); - ot = duint32(s, ot, n); - ot = dsymptr(s, ot, s, ot+1*(widthptr+2*4)+n*widthptr); - ot = duint32(s, ot, t->outtuple); - ot = duint32(s, ot, t->outtuple); + ot = duintxx(s, ot, n, widthint); + ot = duintxx(s, ot, n, widthint); + ot = dsymptr(s, ot, s, ot+1*(widthptr+2*widthint)+n*widthptr); + ot = duintxx(s, ot, t->outtuple, widthint); + ot = duintxx(s, ot, t->outtuple, widthint); // slice data for(t1=getthisx(t)->type; t1; t1=t1->down, n++) @@ -779,9 +834,9 @@ ok: // ../../pkg/runtime/type.go:/InterfaceType ot = dcommontype(s, ot, t); xt = ot - 2*widthptr; - ot = dsymptr(s, ot, s, ot+widthptr+2*4); - ot = duint32(s, ot, n); - ot = duint32(s, ot, n); + ot = dsymptr(s, ot, s, ot+widthptr+2*widthint); + ot = duintxx(s, ot, n, widthint); + ot = duintxx(s, ot, n, widthint); for(a=m; a; a=a->link) { // ../../pkg/runtime/type.go:/imethod ot = dgostringptr(s, ot, a->name); @@ -824,9 +879,9 @@ ok: } ot = dcommontype(s, ot, t); xt = ot - 2*widthptr; - ot = dsymptr(s, ot, s, ot+widthptr+2*4); - ot = duint32(s, ot, n); - ot = duint32(s, ot, n); + ot = dsymptr(s, ot, s, ot+widthptr+2*widthint); + ot = duintxx(s, ot, n, widthint); + ot = duintxx(s, ot, n, widthint); for(t1=t->type; t1!=T; t1=t1->down) { // ../../pkg/runtime/type.go:/structField if(t1->sym && !t1->embedded) { @@ -837,7 +892,10 @@ ok: ot = dgopkgpath(s, ot, t1->sym->pkg); } else { ot = dgostringptr(s, ot, nil); - ot = dgostringptr(s, ot, nil); + if(t1->type->sym != S && t1->type->sym->pkg == builtinpkg) + ot = dgopkgpath(s, ot, localpkg); + else + ot = dgostringptr(s, ot, nil); } ot = dsymptr(s, ot, dtypesym(t1->type), 0); ot = dgostrlitptr(s, ot, t1->note); @@ -846,7 +904,24 @@ ok: break; } ot = dextratype(s, ot, t, xt); - ggloblsym(s, ot, dupok); + ggloblsym(s, ot, dupok, 1); + + // generate typelink.foo pointing at s = type.foo. + // The linker will leave a table of all the typelinks for + // types in the binary, so reflect can find them. + // We only need the link for unnamed composites that + // we want be able to find. + if(t->sym == S) { + switch(t->etype) { + case TARRAY: + case TCHAN: + case TMAP: + slink = typelinksym(t); + dsymptr(slink, 0, s, 0); + ggloblsym(slink, widthptr, dupok, 1); + } + } + return s; } @@ -899,12 +974,14 @@ dumptypestructs(void) // emit type structs for error and func(error) string. // The latter is the type of an auto-generated wrapper. dtypesym(ptrto(errortype)); - dtypesym(functype(nil, + dtypesym(functype(nil, list1(nod(ODCLFIELD, N, typenod(errortype))), list1(nod(ODCLFIELD, N, typenod(types[TSTRING]))))); - + // add paths for runtime and main, which 6l imports implicitly. dimportpath(runtimepkg); + if(flag_race) + dimportpath(racepkg); dimportpath(mkpkg(strlit("main"))); } } @@ -944,7 +1021,180 @@ dalgsym(Type *t) break; } - ggloblsym(s, ot, 1); + ggloblsym(s, ot, 1, 1); return s; } +static int +dgcsym1(Sym *s, int ot, Type *t, vlong *off, int stack_size) +{ + Type *t1; + vlong o, off2, fieldoffset; + + if(t->align > 0 && (*off % t->align) != 0) + fatal("dgcsym1: invalid initial alignment, %T", t); + + switch(t->etype) { + case TINT8: + case TUINT8: + case TINT16: + case TUINT16: + case TINT32: + case TUINT32: + case TINT64: + case TUINT64: + case TINT: + case TUINT: + case TUINTPTR: + case TBOOL: + case TFLOAT32: + case TFLOAT64: + case TCOMPLEX64: + case TCOMPLEX128: + *off += t->width; + break; + + case TPTR32: + case TPTR64: + if(*off % widthptr != 0) + fatal("dgcsym1: invalid alignment, %T", t); + if(!haspointers(t->type) || t->type->etype == TUINT8) { + ot = duintptr(s, ot, GC_APTR); + ot = duintptr(s, ot, *off); + } else { + ot = duintptr(s, ot, GC_PTR); + ot = duintptr(s, ot, *off); + ot = dsymptr(s, ot, dgcsym(t->type), 0); + } + *off += t->width; + break; + + case TCHAN: + case TUNSAFEPTR: + case TFUNC: + if(*off % widthptr != 0) + fatal("dgcsym1: invalid alignment, %T", t); + ot = duintptr(s, ot, GC_APTR); + ot = duintptr(s, ot, *off); + *off += t->width; + break; + + // struct Hmap* + case TMAP: + if(*off % widthptr != 0) + fatal("dgcsym1: invalid alignment, %T", t); + ot = duintptr(s, ot, GC_MAP_PTR); + ot = duintptr(s, ot, *off); + ot = dsymptr(s, ot, dtypesym(t), 0); + *off += t->width; + break; + + // struct { byte *str; int32 len; } + case TSTRING: + if(*off % widthptr != 0) + fatal("dgcsym1: invalid alignment, %T", t); + ot = duintptr(s, ot, GC_STRING); + ot = duintptr(s, ot, *off); + *off += t->width; + break; + + // struct { Itab* tab; void* data; } + // struct { Type* type; void* data; } // When isnilinter(t)==true + case TINTER: + if(*off % widthptr != 0) + fatal("dgcsym1: invalid alignment, %T", t); + if(isnilinter(t)) { + ot = duintptr(s, ot, GC_EFACE); + ot = duintptr(s, ot, *off); + } else { + ot = duintptr(s, ot, GC_IFACE); + ot = duintptr(s, ot, *off); + } + *off += t->width; + break; + + case TARRAY: + if(t->bound < -1) + fatal("dgcsym1: invalid bound, %T", t); + if(isslice(t)) { + // struct { byte* array; uint32 len; uint32 cap; } + if(*off % widthptr != 0) + fatal("dgcsym1: invalid alignment, %T", t); + if(t->type->width != 0) { + ot = duintptr(s, ot, GC_SLICE); + ot = duintptr(s, ot, *off); + ot = dsymptr(s, ot, dgcsym(t->type), 0); + } else { + ot = duintptr(s, ot, GC_APTR); + ot = duintptr(s, ot, *off); + } + *off += t->width; + } else { + if(t->bound < 1 || !haspointers(t->type)) { + *off += t->width; + } else if(t->bound == 1) { + ot = dgcsym1(s, ot, t->type, off, stack_size); // recursive call of dgcsym1 + } else { + if(stack_size < GC_STACK_CAPACITY) { + ot = duintptr(s, ot, GC_ARRAY_START); // a stack push during GC + ot = duintptr(s, ot, *off); + ot = duintptr(s, ot, t->bound); + ot = duintptr(s, ot, t->type->width); + off2 = 0; + ot = dgcsym1(s, ot, t->type, &off2, stack_size+1); // recursive call of dgcsym1 + ot = duintptr(s, ot, GC_ARRAY_NEXT); // a stack pop during GC + } else { + ot = duintptr(s, ot, GC_REGION); + ot = duintptr(s, ot, *off); + ot = duintptr(s, ot, t->width); + ot = dsymptr(s, ot, dgcsym(t), 0); + } + *off += t->width; + } + } + break; + + case TSTRUCT: + o = 0; + for(t1=t->type; t1!=T; t1=t1->down) { + fieldoffset = t1->width; + *off += fieldoffset - o; + ot = dgcsym1(s, ot, t1->type, off, stack_size); // recursive call of dgcsym1 + o = fieldoffset + t1->type->width; + } + *off += t->width - o; + break; + + default: + fatal("dgcsym1: unexpected type %T", t); + } + + return ot; +} + +static Sym* +dgcsym(Type *t) +{ + int ot; + vlong off; + Sym *s; + + s = typesymprefix(".gc", t); + if(s->flags & SymGcgen) + return s; + s->flags |= SymGcgen; + + ot = 0; + off = 0; + ot = duintptr(s, ot, t->width); + ot = dgcsym1(s, ot, t, &off, 0); + ot = duintptr(s, ot, GC_END); + ggloblsym(s, ot, 1, 1); + + if(t->align > 0) + off = rnd(off, t->align); + if(off != t->width) + fatal("dgcsym: off=%lld, size=%lld, type %T", off, t->width, t); + + return s; +} diff --git a/src/cmd/gc/runtime.go b/src/cmd/gc/runtime.go index 15a61d9ef..c49d05c5c 100644 --- a/src/cmd/gc/runtime.go +++ b/src/cmd/gc/runtime.go @@ -45,8 +45,7 @@ func appendslice(typ *byte, x any, y []any) any func appendstr(typ *byte, x []byte, y string) []byte func cmpstring(string, string) int -func slicestring(string, int, int) string -func slicestring1(string, int) string +func eqstring(string, string) bool func intstring(int64) string func slicebytetostring([]byte) string func slicerunetostring([]rune) string @@ -54,14 +53,15 @@ func stringtoslicebyte(string) []byte func stringtoslicerune(string) []rune func stringiter(string, int) int func stringiter2(string, int) (retk int, retv rune) -func copy(to any, fr any, wid uint32) int +func copy(to any, fr any, wid uintptr) int func slicestringcopy(to any, fr any) int // interface conversions +func typ2Itab(typ *byte, typ2 *byte, cache **byte) (ret *byte) func convI2E(elem any) (ret any) func convI2I(typ *byte, elem any) (ret any) func convT2E(typ *byte, elem any) (ret any) -func convT2I(typ *byte, typ2 *byte, elem any) (ret any) +func convT2I(typ *byte, typ2 *byte, cache **byte, elem any) (ret any) // interface type assertions x.(T) func assertE2E(typ *byte, iface any) (ret any) @@ -76,6 +76,8 @@ func assertI2I(typ *byte, iface any) (ret any) func assertI2I2(typ *byte, iface any) (ret any, ok bool) func assertI2T(typ *byte, iface any) (ret any) func assertI2T2(typ *byte, iface any) (ret any, ok bool) +func assertI2TOK(typ *byte, iface any) (ok bool) +func assertE2TOK(typ *byte, iface any) (ok bool) func ifaceeq(i1 any, i2 any) (ret bool) func efaceeq(i1 any, i2 any) (ret bool) @@ -89,7 +91,6 @@ func makemap(mapType *byte, hint int64) (hmap map[any]any) func mapaccess1(mapType *byte, hmap map[any]any, key any) (val any) func mapaccess2(mapType *byte, hmap map[any]any, key any) (val any, pres bool) func mapassign1(mapType *byte, hmap map[any]any, key any, val any) -func mapassign2(mapType *byte, hmap map[any]any, key any, val any, pres bool) func mapiterinit(mapType *byte, hmap map[any]any, hiter *any) func mapdelete(mapType *byte, hmap map[any]any, key any) func mapiternext(hiter *any) @@ -107,7 +108,7 @@ func selectnbsend(chanType *byte, hchan chan<- any, elem any) bool func selectnbrecv(chanType *byte, elem *any, hchan <-chan any) bool func selectnbrecv2(chanType *byte, elem *any, received *bool, hchan <-chan any) bool -func newselect(size int) (sel *byte) +func newselect(size int32) (sel *byte) func selectsend(sel *byte, hchan chan<- any, elem *any) (selected bool) func selectrecv(sel *byte, hchan <-chan any, elem *any) (selected bool) func selectrecv2(sel *byte, hchan <-chan any, elem *any, received *bool) (selected bool) @@ -117,11 +118,6 @@ func block() func makeslice(typ *byte, nel int64, cap int64) (ary []any) func growslice(typ *byte, old []any, n int64) (ary []any) -func sliceslice1(old []any, lb uint64, width uint64) (ary []any) -func sliceslice(old []any, lb uint64, hb uint64, width uint64) (ary []any) -func slicearray(old *any, nel uint64, lb uint64, hb uint64, width uint64) (ary []any) - -func closure() // has args, but compiler fills in func memequal(eq *bool, size uintptr, x, y *any) func memequal8(eq *bool, size uintptr, x, y *any) @@ -141,3 +137,9 @@ func int64tofloat64(int64) float64 func uint64tofloat64(uint64) float64 func complex128div(num complex128, den complex128) (quo complex128) + +// race detection +func racefuncenter(uintptr) +func racefuncexit() +func raceread(uintptr) +func racewrite(uintptr) diff --git a/src/cmd/gc/select.c b/src/cmd/gc/select.c index 8ace1d4ee..cd3de8c7b 100644 --- a/src/cmd/gc/select.c +++ b/src/cmd/gc/select.c @@ -62,7 +62,7 @@ typecheckselect(Node *sel) case OAS2RECV: // convert x, ok = <-c into OSELRECV2(x, <-c) with ntest=ok - if(n->right->op != ORECV) { + if(n->rlist->n->op != ORECV) { yyerror("select assignment must have receive on right hand side"); break; } @@ -70,6 +70,7 @@ typecheckselect(Node *sel) n->left = n->list->n; n->ntest = n->list->next->n; n->right = n->rlist->n; + n->rlist = nil; break; case ORECV: @@ -146,7 +147,7 @@ walkselect(Node *sel) a = nod(OAS2, N, N); a->list = n->list; - a->rlist = n->rlist; + a->rlist = list1(n->right); n = a; typecheck(&n, Etop); break; @@ -296,15 +297,15 @@ walkselect(Node *sel) setlineno(cas); n = cas->left; r = nod(OIF, N, N); - r->nbody = cas->ninit; + r->ninit = cas->ninit; cas->ninit = nil; if(n != nil) { - r->nbody = concat(r->nbody, n->ninit); + r->ninit = concat(r->ninit, n->ninit); n->ninit = nil; } if(n == nil) { // selectdefault(sel *byte); - r->ntest = mkcall("selectdefault", types[TBOOL], &init, var); + r->ntest = mkcall("selectdefault", types[TBOOL], &r->ninit, var); } else { switch(n->op) { default: @@ -312,25 +313,25 @@ walkselect(Node *sel) case OSEND: // selectsend(sel *byte, hchan *chan any, elem *any) (selected bool); - n->left = safeexpr(n->left, &r->ninit); + n->left = localexpr(safeexpr(n->left, &r->ninit), n->left->type, &r->ninit); n->right = localexpr(n->right, n->left->type->type, &r->ninit); n->right = nod(OADDR, n->right, N); n->right->etype = 1; // pointer does not escape typecheck(&n->right, Erv); r->ntest = mkcall1(chanfn("selectsend", 2, n->left->type), types[TBOOL], - &init, var, n->left, n->right); + &r->ninit, var, n->left, n->right); break; case OSELRECV: // selectrecv(sel *byte, hchan *chan any, elem *any) (selected bool); r->ntest = mkcall1(chanfn("selectrecv", 2, n->right->left->type), types[TBOOL], - &init, var, n->right->left, n->left); + &r->ninit, var, n->right->left, n->left); break; case OSELRECV2: // selectrecv2(sel *byte, hchan *chan any, elem *any, received *bool) (selected bool); r->ntest = mkcall1(chanfn("selectrecv2", 2, n->right->left->type), types[TBOOL], - &init, var, n->right->left, n->left, n->ntest); + &r->ninit, var, n->right->left, n->left, n->ntest); break; } } diff --git a/src/cmd/gc/sinit.c b/src/cmd/gc/sinit.c index c8796f8b7..353fc00ce 100644 --- a/src/cmd/gc/sinit.c +++ b/src/cmd/gc/sinit.c @@ -37,6 +37,12 @@ init1(Node *n, NodeList **out) for(l=n->list; l; l=l->next) init1(l->n, out); + if(n->left && n->type && n->left->op == OTYPE && n->class == PFUNC) { + // Methods called as Type.Method(receiver, ...). + // Definitions for method expressions are stored in type->nname. + init1(n->type->nname, out); + } + if(n->op != ONAME) return; switch(n->class) { @@ -78,6 +84,11 @@ init1(Node *n, NodeList **out) } n->initorder = InitPending; l = malloc(sizeof *l); + if(l == nil) { + flusherrors(); + yyerror("out of memory"); + errorexit(); + } l->next = initlist; l->n = n; l->end = nil; @@ -97,6 +108,13 @@ init1(Node *n, NodeList **out) case OAS: if(n->defn->left != n) goto bad; + if(isblank(n->defn->left) && candiscard(n->defn->right)) { + n->defn->op = OEMPTY; + n->defn->left = N; + n->defn->right = N; + break; + } + /* n->defn->dodata = 1; init1(n->defn->right, out); @@ -167,6 +185,11 @@ init2(Node *n, NodeList **out) init2list(n->rlist, out); init2list(n->nbody, out); init2list(n->nelse, out); + + if(n->op == OCLOSURE) + init2list(n->closure->nbody, out); + if(n->op == ODOTMETH) + init2(n->type->nname, out); } static void @@ -291,9 +314,9 @@ staticcopy(Node *l, Node *r, NodeList **out) n1.xoffset = l->xoffset + Array_array; gdata(&n1, nod(OADDR, a, N), widthptr); n1.xoffset = l->xoffset + Array_nel; - gdata(&n1, r->right, 4); + gdata(&n1, r->right, widthint); n1.xoffset = l->xoffset + Array_cap; - gdata(&n1, r->right, 4); + gdata(&n1, r->right, widthint); return 1; } // fall through @@ -394,9 +417,9 @@ staticassign(Node *l, Node *r, NodeList **out) n1.xoffset = l->xoffset + Array_array; gdata(&n1, nod(OADDR, a, N), widthptr); n1.xoffset = l->xoffset + Array_nel; - gdata(&n1, r->right, 4); + gdata(&n1, r->right, widthint); n1.xoffset = l->xoffset + Array_cap; - gdata(&n1, r->right, 4); + gdata(&n1, r->right, widthint); // Fall through to init underlying array. l = a; } @@ -747,7 +770,7 @@ slicelit(int ctxt, Node *n, Node *var, NodeList **init) index = r->left; value = r->right; a = nod(OINDEX, var, index); - a->etype = 1; // no bounds checking + a->bounded = 1; // TODO need to check bounds? switch(value->op) { @@ -879,11 +902,11 @@ ctxt = 0; index = temp(types[TINT]); a = nod(OINDEX, vstat, index); - a->etype = 1; // no bounds checking + a->bounded = 1; a = nod(ODOT, a, newname(symb)); r = nod(OINDEX, vstat, index); - r->etype = 1; // no bounds checking + r->bounded = 1; r = nod(ODOT, r, newname(syma)); r = nod(OINDEX, var, r); @@ -930,7 +953,7 @@ void anylit(int ctxt, Node *n, Node *var, NodeList **init) { Type *t; - Node *a, *vstat; + Node *a, *vstat, *r; t = n->type; switch(n->op) { @@ -941,7 +964,14 @@ anylit(int ctxt, Node *n, Node *var, NodeList **init) if(!isptr[t->etype]) fatal("anylit: not ptr"); - a = nod(OAS, var, callnew(t->type)); + r = nod(ONEW, N, N); + r->typecheck = 1; + r->type = t; + r->esc = n->esc; + walkexpr(&r, init); + + a = nod(OAS, var, r); + typecheck(&a, Etop); *init = list(*init, a); @@ -1223,11 +1253,11 @@ slice: gdata(&nam, nl, types[tptr]->width); nam.xoffset += Array_nel-Array_array; - nodconst(&nod1, types[TINT32], nr->type->bound); - gdata(&nam, &nod1, types[TINT32]->width); + nodconst(&nod1, types[TINT], nr->type->bound); + gdata(&nam, &nod1, widthint); nam.xoffset += Array_cap-Array_nel; - gdata(&nam, &nod1, types[TINT32]->width); + gdata(&nam, &nod1, widthint); goto yes; diff --git a/src/cmd/gc/subr.c b/src/cmd/gc/subr.c index bd53520df..c53eaf285 100644 --- a/src/cmd/gc/subr.c +++ b/src/cmd/gc/subr.c @@ -142,18 +142,32 @@ yyerror(char *fmt, ...) if(debug['x']) print("yyerror: yystate=%d yychar=%d\n", yystate, yychar); + // An unexpected EOF caused a syntax error. Use the previous + // line number since getc generated a fake newline character. + if(curio.eofnl) + lexlineno = prevlineno; + // only one syntax error per line if(lastsyntax == lexlineno) return; lastsyntax = lexlineno; - - if(strstr(fmt, "{ or {")) { + + if(strstr(fmt, "{ or {") || strstr(fmt, " or ?") || strstr(fmt, " or @")) { // The grammar has { and LBRACE but both show up as {. // Rewrite syntax error referring to "{ or {" to say just "{". strecpy(buf, buf+sizeof buf, fmt); p = strstr(buf, "{ or {"); if(p) memmove(p+1, p+6, strlen(p+6)+1); + + // The grammar has ? and @ but only for reading imports. + // Silence them in ordinary errors. + p = strstr(buf, " or ?"); + if(p) + memmove(p, p+5, strlen(p+5)+1); + p = strstr(buf, " or @"); + if(p) + memmove(p, p+5, strlen(p+5)+1); fmt = buf; } @@ -214,6 +228,8 @@ warnl(int line, char *fmt, ...) va_start(arg, fmt); adderr(line, fmt, arg); va_end(arg); + if(debug['m']) + flusherrors(); } void @@ -377,6 +393,7 @@ importdot(Pkg *opkg, Node *pack) Sym *s, *s1; uint32 h; int n; + char *pkgerror; n = 0; for(h=0; h<NHASH; h++) { @@ -389,12 +406,14 @@ importdot(Pkg *opkg, Node *pack) continue; s1 = lookup(s->name); if(s1->def != N) { - redeclare(s1, "during import"); + pkgerror = smprint("during import \"%Z\"", opkg->path); + redeclare(s1, pkgerror); continue; } s1->def = s->def; s1->block = s->block; s1->def->pack = pack; + s1->origpkg = opkg; n++; } } @@ -494,6 +513,31 @@ nod(int op, Node *nleft, Node *nright) return n; } +void +saveorignode(Node *n) +{ + Node *norig; + + if(n->orig != N) + return; + norig = nod(n->op, N, N); + *norig = *n; + n->orig = norig; +} + +// ispaddedfield returns whether the given field +// is followed by padding. For the case where t is +// the last field, total gives the size of the enclosing struct. +static int +ispaddedfield(Type *t, vlong total) +{ + if(t->etype != TFIELD) + fatal("ispaddedfield called non-field %T", t); + if(t->down == T) + return t->width + t->type->width != total; + return t->width + t->type->width != t->down->width; +} + int algtype1(Type *t, Type **bad) { @@ -571,8 +615,12 @@ algtype1(Type *t, Type **bad) } ret = AMEM; for(t1=t->type; t1!=T; t1=t1->down) { - if(isblanksym(t1->sym)) + // Blank fields and padding must be ignored, + // so need special compare. + if(isblanksym(t1->sym) || ispaddedfield(t1, t->width)) { + ret = -1; continue; + } a = algtype1(t1->type, bad); if(a == ANOEQ) return ANOEQ; // not comparable @@ -813,6 +861,7 @@ treecopy(Node *n) default: m = nod(OXXX, N, N); *m = *n; + m->orig = m; m->left = treecopy(n->left); m->right = treecopy(n->right); m->list = listtreecopy(n->list); @@ -1214,7 +1263,7 @@ assignop(Type *src, Type *dst, char **why) return 0; } if(src->etype == TINTER && dst->etype != TBLANK) { - if(why != nil) + if(why != nil && implements(dst, src, &missing, &have, &ptr)) *why = ": need type assertion"; return 0; } @@ -1379,6 +1428,7 @@ assignconv(Node *n, Type *t, char *context) r->type = t; r->typecheck = 1; r->implicit = 1; + r->orig = n->orig; return r; } @@ -2029,11 +2079,13 @@ cheapexpr(Node *n, NodeList **init) /* * return n in a local variable of type t if it is not already. + * the value is guaranteed not to change except by direct + * assignment to it. */ Node* localexpr(Node *n, Type *t, NodeList **init) { - if(n->op == ONAME && + if(n->op == ONAME && !n->addrtaken && (n->class == PAUTO || n->class == PPARAM || n->class == PPARAMOUT) && convertop(n->type, t, nil) == OCONVNOP) return n; @@ -2508,6 +2560,9 @@ genwrapper(Type *rcvr, Type *method, Sym *newnam, int iface) funcbody(fn); curfn = fn; + // wrappers where T is anonymous (struct{ NamedType }) can be duplicated. + if(rcvr->etype == TSTRUCT || isptr[rcvr->etype] && rcvr->type->etype == TSTRUCT) + fn->dupok = 1; typecheck(&fn, Etop); typechecklist(fn->nbody, Etop); curfn = nil; @@ -2591,7 +2646,7 @@ genhash(Sym *sym, Type *t) Node *hashel; Type *first, *t1; int old_safemode; - int64 size, mul; + int64 size, mul, offend; if(debug['r']) print("genhash %S %T\n", sym, t); @@ -2664,7 +2719,7 @@ genhash(Sym *sym, Type *t) call->list = list(call->list, nh); call->list = list(call->list, nodintconst(t->type->width)); nx = nod(OINDEX, np, ni); - nx->etype = 1; // no bounds check + nx->bounded = 1; na = nod(OADDR, nx, N); na->etype = 1; // no escape to heap call->list = list(call->list, na); @@ -2677,22 +2732,21 @@ genhash(Sym *sym, Type *t) // Walk the struct using memhash for runs of AMEM // and calling specific hash functions for the others. first = T; + offend = 0; for(t1=t->type;; t1=t1->down) { - if(t1 != T && (isblanksym(t1->sym) || algtype1(t1->type, nil) == AMEM)) { - if(first == T && !isblanksym(t1->sym)) + if(t1 != T && algtype1(t1->type, nil) == AMEM && !isblanksym(t1->sym)) { + offend = t1->width + t1->type->width; + if(first == T) first = t1; - continue; + // If it's a memory field but it's padded, stop here. + if(ispaddedfield(t1, t->width)) + t1 = t1->down; + else + continue; } // Run memhash for fields up to this one. - while(first != T && isblanksym(first->sym)) - first = first->down; if(first != T) { - if(first->down == t1) - size = first->type->width; - else if(t1 == T) - size = t->width - first->width; // first->width is offset - else - size = t1->width - first->width; // both are offsets + size = offend - first->width; // first->width is offset hashel = hashmem(first->type); // hashel(h, size, &p.first) call = nod(OCALL, hashel, N); @@ -2708,6 +2762,8 @@ genhash(Sym *sym, Type *t) } if(t1 == T) break; + if(isblanksym(t1->sym)) + continue; // Run hash for this field. hashel = hashfor(t1->type); @@ -2721,6 +2777,8 @@ genhash(Sym *sym, Type *t) call->list = list(call->list, na); fn->nbody = list(fn->nbody, call); } + // make sure body is not empty. + fn->nbody = list(fn->nbody, nod(ORETURN, N, N)); break; } @@ -2822,6 +2880,7 @@ geneq(Sym *sym, Type *t) Type *t1, *first; int old_safemode; int64 size; + int64 offend; if(debug['r']) print("geneq %S %T\n", sym, t); @@ -2875,9 +2934,9 @@ geneq(Sym *sym, Type *t) // if p[i] != q[i] { *eq = false; return } nx = nod(OINDEX, np, ni); - nx->etype = 1; // no bounds check + nx->bounded = 1; ny = nod(OINDEX, nq, ni); - ny->etype = 1; // no bounds check + ny->bounded = 1; nif = nod(OIF, N, N); nif->ntest = nod(ONE, nx, ny); @@ -2893,18 +2952,23 @@ geneq(Sym *sym, Type *t) case TSTRUCT: // Walk the struct using memequal for runs of AMEM // and calling specific equality tests for the others. + // Skip blank-named fields. first = T; + offend = 0; for(t1=t->type;; t1=t1->down) { - if(t1 != T && (isblanksym(t1->sym) || algtype1(t1->type, nil) == AMEM)) { - if(first == T && !isblanksym(t1->sym)) + if(t1 != T && algtype1(t1->type, nil) == AMEM && !isblanksym(t1->sym)) { + offend = t1->width + t1->type->width; + if(first == T) first = t1; - continue; + // If it's a memory field but it's padded, stop here. + if(ispaddedfield(t1, t->width)) + t1 = t1->down; + else + continue; } // Run memequal for fields up to this one. // TODO(rsc): All the calls to newname are wrong for // cross-package unexported fields. - while(first != T && isblanksym(first->sym)) - first = first->down; if(first != T) { if(first->down == t1) { fn->nbody = list(fn->nbody, eqfield(np, nq, newname(first->sym), neq)); @@ -2915,16 +2979,15 @@ geneq(Sym *sym, Type *t) fn->nbody = list(fn->nbody, eqfield(np, nq, newname(first->sym), neq)); } else { // More than two fields: use memequal. - if(t1 == T) - size = t->width - first->width; // first->width is offset - else - size = t1->width - first->width; // both are offsets + size = offend - first->width; // first->width is offset fn->nbody = list(fn->nbody, eqmem(np, nq, newname(first->sym), size, neq)); } first = T; } if(t1 == T) break; + if(isblanksym(t1->sym)) + continue; // Check this field, which is not just memory. fn->nbody = list(fn->nbody, eqfield(np, nq, newname(t1->sym), neq)); @@ -3031,7 +3094,7 @@ implements(Type *t, Type *iface, Type **m, Type **samename, int *ptr) for(im=iface->type; im; im=im->down) { imtype = methodfunc(im->type, 0); tm = ifacelookdot(im->sym, t, &followptr, 0); - if(tm == T || !eqtype(methodfunc(tm->type, 0), imtype)) { + if(tm == T || tm->nointerface || !eqtype(methodfunc(tm->type, 0), imtype)) { if(tm == T) tm = ifacelookdot(im->sym, t, &followptr, 1); *m = im; @@ -3504,11 +3567,8 @@ umagic(Magic *m) Sym* ngotype(Node *n) { - if(n->sym != S && n->realtype != T) - if(strncmp(n->sym->name, "autotmp_", 8) != 0) - if(strncmp(n->sym->name, "statictmp_", 8) != 0) - return typename(n->realtype)->left->sym; - + if(n->type != T) + return typenamesym(n->type); return S; } @@ -3564,9 +3624,6 @@ mkpkg(Strlit *path) Pkg *p; int h; - if(isbadimport(path)) - errorexit(); - h = stringhash(path->s) & (nelem(phash)-1); for(p=phash[h]; p; p=p->link) if(p->path->len == path->len && memcmp(path->s, p->path->s, path->len) == 0) @@ -3615,9 +3672,15 @@ addinit(Node **np, NodeList *init) n->ullman = UINF; } +static char* reservedimports[] = { + "go", + "type", +}; + int isbadimport(Strlit *path) { + int i; char *s; Rune r; @@ -3625,6 +3688,13 @@ isbadimport(Strlit *path) yyerror("import path contains NUL"); return 1; } + + for(i=0; i<nelem(reservedimports); i++) { + if(strcmp(path->s, reservedimports[i]) == 0) { + yyerror("import path \"%s\" is reserved and cannot be used", path->s); + return 1; + } + } s = path->s; while(*s) { diff --git a/src/cmd/gc/swt.c b/src/cmd/gc/swt.c index f1a95587f..a497b8622 100644 --- a/src/cmd/gc/swt.c +++ b/src/cmd/gc/swt.c @@ -117,12 +117,15 @@ exprcmp(Case *c1, Case *c2) n1 = c1->node->left; n2 = c2->node->left; + // sort by type (for switches on interface) ct = n1->val.ctype; - if(ct != n2->val.ctype) { - // invalid program, but return a sort - // order so that we can give a better - // error later. + if(ct != n2->val.ctype) return ct - n2->val.ctype; + if(!eqtype(n1->type, n2->type)) { + if(n1->type->vargen > n2->type->vargen) + return +1; + else + return -1; } // sort by constant value @@ -259,10 +262,11 @@ casebody(Node *sw, Node *typeswvar) Node *go, *br; int32 lno, needvar; - lno = setlineno(sw); if(sw->list == nil) return; + lno = setlineno(sw); + cas = nil; // cases stat = nil; // statements def = N; // defaults @@ -270,7 +274,7 @@ casebody(Node *sw, Node *typeswvar) for(l=sw->list; l; l=l->next) { n = l->n; - lno = setlineno(n); + setlineno(n); if(n->op != OXCASE) fatal("casebody %O", n->op); n->op = OCASE; @@ -378,6 +382,7 @@ mkcaselist(Node *sw, int arg) case Strue: case Sfalse: c->type = Texprvar; + c->hash = typehash(n->left->type); switch(consttype(n->left)) { case CTFLT: case CTINT: @@ -442,6 +447,10 @@ exprbsw(Case *c0, int ncase, int arg) n = c0->node; lno = setlineno(n); + if(assignop(n->left->type, exprname->type, nil) == OCONVIFACE || + assignop(exprname->type, n->left->type, nil) == OCONVIFACE) + goto snorm; + switch(arg) { case Strue: a = nod(OIF, N, N); @@ -457,6 +466,7 @@ exprbsw(Case *c0, int ncase, int arg) break; default: + snorm: a = nod(OIF, N, N); a->ntest = nod(OEQ, exprname, n->left); // if name == val typecheck(&a->ntest, Erv); @@ -520,6 +530,8 @@ exprswitch(Node *sw) exprname = temp(sw->ntest->type); cas = list1(nod(OAS, exprname, sw->ntest)); typechecklist(cas, Etop); + } else { + exprname = nodbool(arg == Strue); } c0 = mkcaselist(sw, arg); @@ -786,7 +798,6 @@ typeswitch(Node *sw) void walkswitch(Node *sw) { - /* * reorder the body into (OLIST, cases, statements) * cases have OGOTO into statements. @@ -813,7 +824,7 @@ typecheckswitch(Node *n) { int top, lno, ptr; char *nilonly; - Type *t, *missing, *have; + Type *t, *badtype, *missing, *have; NodeList *l, *ll; Node *ncase, *nvar; Node *def; @@ -839,10 +850,14 @@ typecheckswitch(Node *n) } else t = types[TBOOL]; if(t) { - if(!okforeq[t->etype] || isfixedarray(t)) + if(!okforeq[t->etype]) yyerror("cannot switch on %lN", n->ntest); - else if(t->etype == TARRAY) + else if(t->etype == TARRAY && !isfixedarray(t)) nilonly = "slice"; + else if(t->etype == TARRAY && isfixedarray(t) && algtype1(t, nil) == ANOEQ) + yyerror("cannot switch on %lN", n->ntest); + else if(t->etype == TSTRUCT && algtype1(t, &badtype) == ANOEQ) + yyerror("cannot switch on %lN (struct containing %T cannot be compared)", n->ntest, badtype); else if(t->etype == TFUNC) nilonly = "func"; else if(t->etype == TMAP) @@ -889,7 +904,7 @@ typecheckswitch(Node *n) yyerror("%lN is not a type", ll->n); // reset to original type ll->n = n->ntest->right; - } else if(ll->n->type->etype != TINTER && !implements(ll->n->type, t, &missing, &have, &ptr)) { + } else if(ll->n->type->etype != TINTER && t->etype == TINTER && !implements(ll->n->type, t, &missing, &have, &ptr)) { if(have && !missing->broke && !have->broke) yyerror("impossible type switch case: %lN cannot have dynamic type %T" " (wrong type for %S method)\n\thave %S%hT\n\twant %S%hT", diff --git a/src/cmd/gc/typecheck.c b/src/cmd/gc/typecheck.c index cc4faf5a7..fbab85d03 100644 --- a/src/cmd/gc/typecheck.c +++ b/src/cmd/gc/typecheck.c @@ -31,6 +31,8 @@ static void checkassign(Node*); static void checkassignlist(NodeList*); static void stringtoarraylit(Node**); static Node* resolve(Node*); +static void checkdefergo(Node*); +static int checkmake(Type*, char*, Node*); static NodeList* typecheckdefstack; @@ -106,6 +108,27 @@ typekind(Type *t) } /* + * sprint_depchain prints a dependency chain + * of nodes into fmt. + * It is used by typecheck in the case of OLITERAL nodes + * to print constant definition loops. + */ +static void +sprint_depchain(Fmt *fmt, NodeList *stack, Node *cur, Node *first) +{ + NodeList *l; + + for(l = stack; l; l=l->next) { + if(l->n->op == cur->op) { + if(l->n != first) + sprint_depchain(fmt, l->next, l->n, first); + fmtprint(fmt, "\n\t%L: %N uses %N", l->n->lineno, l->n, cur); + return; + } + } +} + +/* * type check node *np. * replaces *np with a new pointer in some cases. * returns the final value of *np as a convenience. @@ -155,6 +178,24 @@ typecheck(Node **np, int top) } if(n->typecheck == 2) { + // Typechecking loop. Trying printing a meaningful message, + // otherwise a stack trace of typechecking. + switch(n->op) { + case ONAME: + // We can already diagnose variables used as types. + if((top & (Erv|Etype)) == Etype) + yyerror("%N is not a type", n); + break; + case OLITERAL: + if((top & (Erv|Etype)) == Etype) { + yyerror("%N is not a type", n); + break; + } + fmtstrinit(&fmt); + sprint_depchain(&fmt, tcstack, n, n); + yyerrorl(n->lineno, "constant definition loop%s", fmtstrflush(&fmt)); + break; + } if(nsavederrors+nerrors == 0) { fmtstrinit(&fmt); for(l=tcstack; l; l=l->next) @@ -165,7 +206,7 @@ typecheck(Node **np, int top) return n; } n->typecheck = 2; - + if(tcfree != nil) { l = tcfree; tcfree = l->next; @@ -206,6 +247,12 @@ callrecv(Node *n) case OCALLINTER: case OCALLFUNC: case ORECV: + case OCAP: + case OLEN: + case OCOPY: + case ONEW: + case OAPPEND: + case ODELETE: return 1; } @@ -249,7 +296,6 @@ typecheck1(Node **np, int top) } typecheckdef(n); - n->realtype = n->type; if(n->op == ONONAME) goto error; } @@ -331,8 +377,11 @@ reswitch: t->bound = -1; // slice } else if(l->op == ODDD) { t->bound = -100; // to be filled in - if(!(top&Ecomplit)) + if(!(top&Ecomplit) && !n->diag) { + t->broke = 1; + n->diag = 1; yyerror("use of [...] array outside of array literal"); + } } else { l = typecheck(&n->left, Erv); switch(consttype(l)) { @@ -351,8 +400,10 @@ reswitch: if(t->bound < 0) { yyerror("array bound must be non-negative"); goto error; - } else - overflow(v, types[TINT]); + } else if(doesoverflow(v, types[TINT])) { + yyerror("array bound is too large"); + goto error; + } } typecheck(&r, Etype); if(r->type == T) @@ -396,7 +447,7 @@ reswitch: ok |= Etype; n->op = OTYPE; n->type = tostruct(n->list); - if(n->type == T) + if(n->type == T || n->type->broke) goto error; n->list = nil; break; @@ -436,8 +487,11 @@ reswitch: goto ret; } if(!isptr[t->etype]) { - yyerror("invalid indirect of %lN", n->left); - goto error; + if(top & (Erv | Etop)) { + yyerror("invalid indirect of %lN", n->left); + goto error; + } + goto ret; } ok |= Erv; n->type = t->type; @@ -567,7 +621,10 @@ reswitch: n->left = l; n->right = r; } - } + // non-comparison operators on ideal bools should make them lose their ideal-ness + } else if(t == idealbool) + t = types[TBOOL]; + if(et == TSTRING) { if(iscmp[n->op]) { n->etype = n->op; @@ -587,6 +644,13 @@ reswitch: n->op = OCMPIFACE; } } + + if((op == ODIV || op == OMOD) && isconst(r, CTINT)) + if(mpcmpfixc(r->val.u.xval, 0) == 0) { + yyerror("division by zero"); + goto error; + } + n->type = t; goto ret; @@ -697,6 +761,10 @@ reswitch: n->op = ODOTPTR; checkwidth(t); } + if(isblank(n->right)) { + yyerror("cannot refer to blank field or method"); + goto error; + } if(!lookdot(n, t, 0)) { if(lookdot(n, t, 1)) yyerror("%N undefined (cannot refer to unexported field or method %S)", n, n->right->sym); @@ -735,14 +803,20 @@ reswitch: } if(n->type != T && n->type->etype != TINTER) if(!implements(n->type, t, &missing, &have, &ptr)) { - if(have) - yyerror("impossible type assertion: %lN cannot have dynamic type %T" - " (wrong type for %S method)\n\thave %S%hT\n\twant %S%hT", - l, n->type, missing->sym, have->sym, have->type, - missing->sym, missing->type); + if(have && have->sym == missing->sym) + yyerror("impossible type assertion:\n\t%T does not implement %T (wrong type for %S method)\n" + "\t\thave %S%hhT\n\t\twant %S%hhT", n->type, t, missing->sym, + have->sym, have->type, missing->sym, missing->type); + else if(ptr) + yyerror("impossible type assertion:\n\t%T does not implement %T (%S method requires pointer receiver)", + n->type, t, missing->sym); + else if(have) + yyerror("impossible type assertion:\n\t%T does not implement %T (missing %S method)\n" + "\t\thave %S%hhT\n\t\twant %S%hhT", n->type, t, missing->sym, + have->sym, have->type, missing->sym, missing->type); else - yyerror("impossible type assertion: %lN cannot have dynamic type %T" - " (missing %S method)", l, n->type, missing->sym); + yyerror("impossible type assertion:\n\t%T does not implement %T (missing %S method)", + n->type, t, missing->sym); goto error; } goto ret; @@ -762,11 +836,35 @@ reswitch: yyerror("invalid operation: %N (index of type %T)", n, t); goto error; + + case TSTRING: case TARRAY: defaultlit(&n->right, T); - if(n->right->type != T && !isint[n->right->type->etype]) - yyerror("non-integer array index %N", n->right); - n->type = t->type; + if(t->etype == TSTRING) + n->type = types[TUINT8]; + else + n->type = t->type; + why = "string"; + if(t->etype == TARRAY) { + if(isfixedarray(t)) + why = "array"; + else + why = "slice"; + } + if(n->right->type != T && !isint[n->right->type->etype]) { + yyerror("non-integer %s index %N", why, n->right); + break; + } + if(n->right->op == OLITERAL) { + if(mpgetfix(n->right->val.u.xval) < 0) + yyerror("invalid %s index %N (index must be non-negative)", why, n->right); + else if(isfixedarray(t) && t->bound > 0 && mpgetfix(n->right->val.u.xval) >= t->bound) + yyerror("invalid array index %N (out of bounds for %d-element array)", n->right, t->bound); + else if(isconst(n->left, CTSTR) && mpgetfix(n->right->val.u.xval) >= n->left->val.u.sval->len) + yyerror("invalid string index %N (out of bounds for %d-byte string)", n->right, n->left->val.u.sval->len); + else if(mpcmpfixfix(n->right->val.u.xval, maxintval[TINT]) > 0) + yyerror("invalid %s index %N (index too large)", why, n->right); + } break; case TMAP: @@ -777,13 +875,6 @@ reswitch: n->type = t->type; n->op = OINDEXMAP; break; - - case TSTRING: - defaultlit(&n->right, types[TUINT]); - if(n->right->type != T && !isint[n->right->type->etype]) - yyerror("non-integer string index %N", n->right); - n->type = types[TUINT8]; - break; } goto ret; @@ -843,7 +934,8 @@ reswitch: defaultlit(&n->left, T); defaultlit(&n->right->left, T); defaultlit(&n->right->right, T); - if(isfixedarray(n->left->type)) { + l = n->left; + if(isfixedarray(l->type)) { if(!islvalue(n->left)) { yyerror("invalid operation %N (slice of unaddressable value)", n); goto error; @@ -851,6 +943,26 @@ reswitch: n->left = nod(OADDR, n->left, N); n->left->implicit = 1; typecheck(&n->left, Erv); + l = n->left; + } + if((t = l->type) == T) + goto error; + tp = nil; + if(istype(t, TSTRING)) { + n->type = t; + n->op = OSLICESTR; + } else if(isptr[t->etype] && isfixedarray(t->type)) { + tp = t->type; + n->type = typ(TARRAY); + n->type->type = tp->type; + n->type->bound = -1; + dowidth(n->type); + n->op = OSLICEARR; + } else if(isslice(t)) { + n->type = t; + } else { + yyerror("cannot slice %N (type %T)", l, t); + goto error; } if(n->right->left != N) { if((t = n->right->left->type) == T) @@ -859,6 +971,18 @@ reswitch: yyerror("invalid slice index %N (type %T)", n->right->left, t); goto error; } + if(n->right->left->op == OLITERAL) { + if(mpgetfix(n->right->left->val.u.xval) < 0) { + yyerror("invalid slice index %N (index must be non-negative)", n->right->left); + goto error; + } else if(tp != nil && tp->bound > 0 && mpgetfix(n->right->left->val.u.xval) > tp->bound) { + yyerror("invalid slice index %N (out of bounds for %d-element array)", n->right->left, tp->bound); + goto error; + } else if(mpcmpfixfix(n->right->left->val.u.xval, maxintval[TINT]) > 0) { + yyerror("invalid slice index %N (index too large)", n->right->left); + goto error; + } + } } if(n->right->right != N) { if((t = n->right->right->type) == T) @@ -867,29 +991,28 @@ reswitch: yyerror("invalid slice index %N (type %T)", n->right->right, t); goto error; } + if(n->right->right->op == OLITERAL) { + if(mpgetfix(n->right->right->val.u.xval) < 0) { + yyerror("invalid slice index %N (index must be non-negative)", n->right->right); + goto error; + } else if(tp != nil && tp->bound > 0 && mpgetfix(n->right->right->val.u.xval) > tp->bound) { + yyerror("invalid slice index %N (out of bounds for %d-element array)", n->right->right, tp->bound); + goto error; + } else if(mpcmpfixfix(n->right->right->val.u.xval, maxintval[TINT]) > 0) { + yyerror("invalid slice index %N (index too large)", n->right->right); + goto error; + } + } } - l = n->left; - if((t = l->type) == T) + if(n->right->left != N + && n->right->right != N + && n->right->left->op == OLITERAL + && n->right->right->op == OLITERAL + && mpcmpfixfix(n->right->left->val.u.xval, n->right->right->val.u.xval) > 0) { + yyerror("inverted slice index %N > %N", n->right->left, n->right->right); goto error; - if(istype(t, TSTRING)) { - n->type = t; - n->op = OSLICESTR; - goto ret; - } - if(isptr[t->etype] && isfixedarray(t->type)) { - n->type = typ(TARRAY); - n->type->type = t->type->type; - n->type->bound = -1; - dowidth(n->type); - n->op = OSLICEARR; - goto ret; - } - if(isslice(t)) { - n->type = t; - goto ret; } - yyerror("cannot slice %N (type %T)", l, t); - goto error; + goto ret; /* * call and call like @@ -916,8 +1039,11 @@ reswitch: defaultlit(&n->left, T); l = n->left; if(l->op == OTYPE) { - if(n->isddd || l->type->bound == -100) - yyerror("invalid use of ... in type conversion", l); + if(n->isddd || l->type->bound == -100) { + if(!l->type->broke) + yyerror("invalid use of ... in type conversion", l); + n->diag = 1; + } // pick off before type-checking arguments ok |= Erv; // turn CALL(type, arg) into CONV(arg) w/ type @@ -929,7 +1055,7 @@ reswitch: goto doconv; } - if(count(n->list) == 1) + if(count(n->list) == 1 && !n->isddd) typecheck(&n->list->n, Erv | Efnstruct); else typechecklist(n->list, Erv); @@ -1011,10 +1137,12 @@ reswitch: if(!iscomplex[t->etype]) goto badcall1; if(isconst(l, CTCPLX)){ + r = n; if(n->op == OREAL) n = nodfltconst(&l->val.u.cval->real); else n = nodfltconst(&l->val.u.cval->imag); + n->orig = r; } n->type = types[cplxsubtype(t->etype)]; goto ret; @@ -1074,7 +1202,9 @@ reswitch: } if(l->op == OLITERAL && r->op == OLITERAL) { // make it a complex literal - n = nodcplxlit(l->val, r->val); + r = nodcplxlit(l->val, r->val); + r->orig = n; + n = r; } n->type = t; goto ret; @@ -1214,17 +1344,25 @@ reswitch: case OCONV: doconv: ok |= Erv; + saveorignode(n); typecheck(&n->left, Erv | (top & (Eindir | Eiota))); convlit1(&n->left, n->type, 1); if((t = n->left->type) == T || n->type == T) goto error; if((n->op = convertop(t, n->type, &why)) == 0) { - yyerror("cannot convert %lN to type %T%s", n->left, n->type, why); + if(!n->diag && !n->type->broke) { + yyerror("cannot convert %lN to type %T%s", n->left, n->type, why); + n->diag = 1; + } n->op = OCONV; } switch(n->op) { case OCONVNOP: if(n->left->op == OLITERAL) { + r = nod(OXXX, N, N); + n->op = OCONV; + n->orig = r; + *r = *n; n->op = OLITERAL; n->val = n->left->val; } @@ -1267,22 +1405,20 @@ reswitch: l = args->n; args = args->next; typecheck(&l, Erv); - defaultlit(&l, types[TINT]); r = N; if(args != nil) { r = args->n; args = args->next; typecheck(&r, Erv); - defaultlit(&r, types[TINT]); } if(l->type == T || (r && r->type == T)) goto error; - if(!isint[l->type->etype]) { - yyerror("non-integer len argument to make(%T)", t); + et = checkmake(t, "len", l) < 0; + et |= r && checkmake(t, "cap", r) < 0; + if(et) goto error; - } - if(r && !isint[r->type->etype]) { - yyerror("non-integer cap argument to make(%T)", t); + if(isconst(l, CTINT) && r && isconst(r, CTINT) && mpcmpfixfix(l->val.u.xval, r->val.u.xval) > 0) { + yyerror("len larger than cap in make(%T)", t); goto error; } n->left = l; @@ -1298,10 +1434,8 @@ reswitch: defaultlit(&l, types[TINT]); if(l->type == T) goto error; - if(!isint[l->type->etype]) { - yyerror("non-integer size argument to make(%T)", t); + if(checkmake(t, "size", l) < 0) goto error; - } n->left = l; } else n->left = nodintconst(0); @@ -1317,10 +1451,8 @@ reswitch: defaultlit(&l, types[TINT]); if(l->type == T) goto error; - if(!isint[l->type->etype]) { - yyerror("non-integer buffer argument to make(%T)", t); + if(checkmake(t, "buffer", l) < 0) goto error; - } n->left = l; } else n->left = nodintconst(0); @@ -1402,6 +1534,21 @@ reswitch: fatal("OITAB of %T", t); n->type = ptrto(types[TUINTPTR]); goto ret; + + case OCLOSUREVAR: + ok |= Erv; + goto ret; + + case OCFUNC: + ok |= Erv; + typecheck(&n->left, Erv); + n->type = types[TUINTPTR]; + goto ret; + + case OCONVNOP: + ok |= Erv; + typecheck(&n->left, Erv); + goto ret; /* * statements @@ -1428,12 +1575,15 @@ reswitch: case ODEFER: ok |= Etop; - typecheck(&n->left, Etop); + typecheck(&n->left, Etop|Erv); + if(!n->left->diag) + checkdefergo(n); goto ret; case OPROC: ok |= Etop; - typecheck(&n->left, Etop|Eproc); + typecheck(&n->left, Etop|Eproc|Erv); + checkdefergo(n); goto ret; case OFOR: @@ -1530,9 +1680,7 @@ ret: } } - // TODO(rsc): should not need to check importpkg, - // but reflect mentions unsafe.Pointer. - if(safemode && !incannedimport && !importpkg && t && t->etype == TUNSAFEPTR) + if(safemode && !incannedimport && !importpkg && !compiling_wrappers && t && t->etype == TUNSAFEPTR) yyerror("cannot use unsafe.Pointer"); evconst(n); @@ -1555,7 +1703,7 @@ ret: } if((top & Etop) && !(top & (Ecall|Erv|Etype)) && !(ok & Etop)) { if(n->diag == 0) { - yyerror("%N not used", n); + yyerror("%N evaluated but not used", n); n->diag = 1; } goto error; @@ -1579,6 +1727,56 @@ out: } static void +checkdefergo(Node *n) +{ + char *what; + + what = "defer"; + if(n->op == OPROC) + what = "go"; + + switch(n->left->op) { + case OCALLINTER: + case OCALLMETH: + case OCALLFUNC: + case OCLOSE: + case OCOPY: + case ODELETE: + case OPANIC: + case OPRINT: + case OPRINTN: + case ORECOVER: + // ok + break; + case OAPPEND: + case OCAP: + case OCOMPLEX: + case OIMAG: + case OLEN: + case OMAKE: + case OMAKESLICE: + case OMAKECHAN: + case OMAKEMAP: + case ONEW: + case OREAL: + case OLITERAL: // conversion or unsafe.Alignof, Offsetof, Sizeof + if(n->left->orig != N && n->left->orig->op == OCONV) + goto conv; + yyerror("%s discards result of %N", what, n->left); + break; + default: + conv: + if(!n->diag) { + // The syntax made sure it was a call, so this must be + // a conversion. + n->diag = 1; + yyerror("%s requires function call, not conversion", what); + } + break; + } +} + +static void implicitstar(Node **nn) { Type *t; @@ -1682,7 +1880,7 @@ lookdot1(Node *errnode, Sym *s, Type *t, Type *f, int dostrcmp) static int looktypedot(Node *n, Type *t, int dostrcmp) { - Type *f1, *f2, *tt; + Type *f1, *f2; Sym *s; s = n->right->sym; @@ -1692,8 +1890,6 @@ looktypedot(Node *n, Type *t, int dostrcmp) if(f1 == T) return 0; - if(f1->width == BADWIDTH) - fatal("lookdot badwidth %T %p", f1, f1); n->right = methodname(n->right, t); n->xoffset = f1->width; n->type = f1->type; @@ -1701,11 +1897,9 @@ looktypedot(Node *n, Type *t, int dostrcmp) return 1; } - tt = t; - if(t->sym == S && isptr[t->etype]) - tt = t->type; - - f2 = methtype(tt, 0); + // Find the base type: methtype will fail if t + // is not of the form T or *T. + f2 = methtype(t, 0); if(f2 == T) return 0; @@ -1769,6 +1963,7 @@ lookdot(Node *n, Type *t, int dostrcmp) fatal("lookdot badwidth %T %p", f1, f1); n->xoffset = f1->width; n->type = f1->type; + n->paramfld = f1; if(t->etype == TINTER) { if(isptr[n->left->type->etype]) { n->left = nod(OIND, n->left, N); // implicitstar @@ -2129,10 +2324,10 @@ static void typecheckcomplit(Node **np) { int bad, i, len, nerr; - Node *l, *n, *r, **hash; + Node *l, *n, *norig, *r, **hash; NodeList *ll; Type *t, *f; - Sym *s; + Sym *s, *s1; int32 lno; ulong nhash; Node *autohash[101]; @@ -2146,14 +2341,18 @@ typecheckcomplit(Node **np) yyerror("missing type in composite literal"); goto error; } - + + // Save original node (including n->right) + norig = nod(n->op, N, N); + *norig = *n; + setlineno(n->right); l = typecheck(&n->right /* sic */, Etype|Ecomplit); if((t = l->type) == T) goto error; nerr = nerrors; n->type = t; - + if(isptr[t->etype]) { // For better or worse, we don't allow pointers as the composite literal type, // except when using the &T syntax, which sets implicit on the OIND. @@ -2161,13 +2360,12 @@ typecheckcomplit(Node **np) yyerror("invalid pointer type %T for composite literal (use &%T instead)", t, t->type); goto error; } - // Also, the underlying type must be a struct, map, slice, or array. if(!iscomptype(t)) { yyerror("invalid pointer type %T for composite literal", t); goto error; } - t = t->type; + t = t->type; } switch(t->etype) { @@ -2298,9 +2496,11 @@ typecheckcomplit(Node **np) // Sym might have resolved to name in other top-level // package, because of import dot. Redirect to correct sym // before we do the lookup. - if(s->pkg != localpkg && exportname(s->name)) - s = lookup(s->name); - + if(s->pkg != localpkg && exportname(s->name)) { + s1 = lookup(s->name); + if(s1->origpkg == s->pkg) + s = s1; + } f = lookdot1(nil, s, t, t->type, 0); if(f == nil) { yyerror("unknown %T field '%S' in struct literal", t, s); @@ -2323,6 +2523,7 @@ typecheckcomplit(Node **np) if(nerr != nerrors) goto error; + n->orig = norig; if(isptr[n->type->etype]) { n = nod(OPTRLIT, n, N); n->typecheck = 1; @@ -2331,6 +2532,7 @@ typecheckcomplit(Node **np) n->left->typecheck = 1; } + n->orig = norig; *np = n; lineno = lno; return; @@ -2527,7 +2729,6 @@ typecheckas2(Node *n) goto common; case ORECV: n->op = OAS2RECV; - n->right = n->rlist->n; goto common; case ODOTTYPE: n->op = OAS2DOTTYPE; @@ -2572,7 +2773,7 @@ typecheckfunc(Node *n) t->nname = n->nname; rcvr = getthisx(t)->type; if(rcvr != nil && n->shortname != N && !isblank(n->shortname)) - addmethod(n->shortname->sym, t, 1); + addmethod(n->shortname->sym, t, 1, n->nname->nointerface); } static void @@ -2715,6 +2916,7 @@ typecheckdeftype(Node *n) typecheck(&n->ntype, Etype); if((t = n->ntype->type) == T) { n->diag = 1; + n->type = T; goto ret; } if(n->type == T) { @@ -2828,14 +3030,14 @@ typecheckdef(Node *n) yyerror("xxx"); } typecheck(&e, Erv | Eiota); - if(e->type != T && e->op != OLITERAL) { - yyerror("const initializer must be constant"); - goto ret; - } if(isconst(e, CTNIL)) { yyerror("const initializer cannot be nil"); goto ret; } + if(e->type != T && e->op != OLITERAL || !isgoconst(e)) { + yyerror("const initializer %N is not a constant", e); + goto ret; + } t = n->type; if(t != T) { if(!okforconst[t->etype]) { @@ -2912,3 +3114,33 @@ ret: n->walkdef = 1; return n; } + +static int +checkmake(Type *t, char *arg, Node *n) +{ + if(n->op == OLITERAL) { + n->val = toint(n->val); + if(mpcmpfixc(n->val.u.xval, 0) < 0) { + yyerror("negative %s argument in make(%T)", arg, t); + return -1; + } + if(mpcmpfixfix(n->val.u.xval, maxintval[TINT]) > 0) { + yyerror("%s argument too large in make(%T)", arg, t); + return -1; + } + + // Delay defaultlit until after we've checked range, to avoid + // a redundant "constant NNN overflows int" error. + defaultlit(&n, types[TINT]); + return 0; + } + + // Defaultlit still necessary for non-constant: n might be 1<<k. + defaultlit(&n, types[TINT]); + + if(!isint[n->type->etype]) { + yyerror("non-integer %s argument in make(%T) - %T", arg, t, n->type); + return -1; + } + return 0; +} diff --git a/src/cmd/gc/walk.c b/src/cmd/gc/walk.c index a4edc9062..de2105ed3 100644 --- a/src/cmd/gc/walk.c +++ b/src/cmd/gc/walk.c @@ -21,7 +21,13 @@ static NodeList* reorder3(NodeList*); static Node* addstr(Node*, NodeList**); static Node* appendslice(Node*, NodeList**); static Node* append(Node*, NodeList**); +static Node* sliceany(Node*, NodeList**); static void walkcompare(Node**, NodeList**); +static void walkrotate(Node**); +static void walkmul(Node**, NodeList**); +static void walkdiv(Node**, NodeList**); +static int bounded(Node*, int64); +static Mpint mpzero; // can this code branch reach the end // without an unconditional RETURN @@ -178,8 +184,8 @@ walkstmt(Node **np) dump("nottop", n); break; - case OASOP: case OAS: + case OASOP: case OAS2: case OAS2DOTTYPE: case OAS2RECV: @@ -368,9 +374,10 @@ walkexpr(Node **np, NodeList **init) NodeList *ll, *lr, *lpost; Type *t; int et; - int64 v, v1, v2, len; + int64 v; int32 lno; - Node *n, *fn; + Node *n, *fn, *n1, *n2; + Sym *sym; char buf[100], *p; n = *np; @@ -409,7 +416,7 @@ walkexpr(Node **np, NodeList **init) switch(n->op) { default: dump("walk", n); - fatal("walkexpr: switch 1 unknown op %N", n); + fatal("walkexpr: switch 1 unknown op %+hN", n); break; case OTYPE: @@ -424,14 +431,23 @@ walkexpr(Node **np, NodeList **init) case OCOM: case OREAL: case OIMAG: - case ODOT: - case ODOTPTR: case ODOTMETH: case ODOTINTER: case OIND: walkexpr(&n->left, init); goto ret; + case ODOT: + case ODOTPTR: + usefield(n); + walkexpr(&n->left, init); + goto ret; + + case OEFACE: + walkexpr(&n->left, init); + walkexpr(&n->right, init); + goto ret; + case OITAB: walkexpr(&n->left, init); goto ret; @@ -454,19 +470,34 @@ walkexpr(Node **np, NodeList **init) case OLSH: case ORSH: + walkexpr(&n->left, init); + walkexpr(&n->right, init); + shiftwalked: + t = n->left->type; + n->bounded = bounded(n->right, 8*t->width); + if(debug['m'] && n->etype && !isconst(n->right, CTINT)) + warn("shift bounds check elided"); + goto ret; + case OAND: - case OOR: - case OXOR: case OSUB: - case OMUL: + case OHMUL: case OLT: case OLE: case OGE: case OGT: case OADD: case OCOMPLEX: + case OLROT: + walkexpr(&n->left, init); + walkexpr(&n->right, init); + goto ret; + + case OOR: + case OXOR: walkexpr(&n->left, init); walkexpr(&n->right, init); + walkrotate(&n); goto ret; case OEQ: @@ -505,6 +536,11 @@ walkexpr(Node **np, NodeList **init) n->addable = 1; goto ret; + case OCLOSUREVAR: + case OCFUNC: + n->addable = 1; + goto ret; + case ONAME: if(!(n->class & PHEAP) && n->class != PPARAMREF) n->addable = 1; @@ -525,10 +561,12 @@ walkexpr(Node **np, NodeList **init) if(n->list && n->list->n->op == OAS) goto ret; + /* if(n->left->op == OCLOSURE) { walkcallclosure(n, init); t = n->left->type; } + */ walkexpr(&n->left, init); walkexprlist(n->list, init); @@ -656,6 +694,31 @@ walkexpr(Node **np, NodeList **init) n->ninit = nil; r = n->rlist->n; walkexprlistsafe(n->list, init); + if(isblank(n->list->n) && !isinter(r->type)) { + strcpy(buf, "assert"); + p = buf+strlen(buf); + if(isnilinter(r->left->type)) + *p++ = 'E'; + else + *p++ = 'I'; + *p++ = '2'; + *p++ = 'T'; + *p++ = 'O'; + *p++ = 'K'; + *p = '\0'; + + fn = syslook(buf, 1); + ll = list1(typename(r->type)); + ll = list(ll, r->left); + argtype(fn, r->left->type); + n1 = nod(OCALL, fn, N); + n1->list = ll; + n = nod(OAS, n->list->next->n, n1); + typecheck(&n, Etop); + walkexpr(&n, init); + goto ret; + } + r->op = ODOTTYPE2; walkexpr(&r, init); ll = ascompatet(n->op, n->list, &r->type, 0, init); @@ -694,10 +757,22 @@ walkexpr(Node **np, NodeList **init) goto ret; case OCONVIFACE: + walkexpr(&n->left, init); + + // Optimize convT2E as a two-word copy when T is uintptr-shaped. + if(!isinter(n->left->type) && isnilinter(n->type) && + (n->left->type->width == widthptr) && + isint[simsimtype(n->left->type)]) { + l = nod(OEFACE, typename(n->left->type), n->left); + l->type = n->type; + l->typecheck = n->typecheck; + n = l; + goto ret; + } + // Build name of function: convI2E etc. // Not all names are possible // (e.g., we'll never generate convE2E or convE2I). - walkexpr(&n->left, init); strcpy(buf, "conv"); p = buf+strlen(buf); if(isnilinter(n->left->type)) @@ -719,6 +794,60 @@ walkexpr(Node **np, NodeList **init) ll = list(ll, typename(n->left->type)); if(!isnilinter(n->type)) ll = list(ll, typename(n->type)); + if(!isinter(n->left->type) && !isnilinter(n->type)){ + sym = pkglookup(smprint("%-T.%-T", n->left->type, n->type), itabpkg); + if(sym->def == N) { + l = nod(ONAME, N, N); + l->sym = sym; + l->type = ptrto(types[TUINT8]); + l->addable = 1; + l->class = PEXTERN; + l->xoffset = 0; + sym->def = l; + ggloblsym(sym, widthptr, 1, 0); + } + l = nod(OADDR, sym->def, N); + l->addable = 1; + ll = list(ll, l); + + if(n->left->type->width == widthptr && + isint[simsimtype(n->left->type)]) { + /* For pointer types, we can make a special form of optimization + * + * These statements are put onto the expression init list: + * Itab *tab = atomicloadtype(&cache); + * if(tab == nil) + * tab = typ2Itab(type, itype, &cache); + * + * The CONVIFACE expression is replaced with this: + * OEFACE{tab, ptr}; + */ + l = temp(ptrto(types[TUINT8])); + + n1 = nod(OAS, l, sym->def); + typecheck(&n1, Etop); + *init = list(*init, n1); + + fn = syslook("typ2Itab", 1); + n1 = nod(OCALL, fn, N); + n1->list = ll; + typecheck(&n1, Erv); + walkexpr(&n1, init); + + n2 = nod(OIF, N, N); + n2->ntest = nod(OEQ, l, nodnil()); + n2->nbody = list1(nod(OAS, l, n1)); + n2->likely = -1; + typecheck(&n2, Etop); + *init = list(*init, n2); + + l = nod(OEFACE, l, n->left); + l->typecheck = n->typecheck; + l->type = n->type; + n = l; + goto ret; + } + } ll = list(ll, n->left); argtype(fn, n->left->type); argtype(fn, n->type); @@ -772,7 +901,7 @@ walkexpr(Node **np, NodeList **init) * on 386, rewrite float ops into l = l op r. * everywhere, rewrite map ops into l = l op r. * everywhere, rewrite string += into l = l op r. - * everywhere, rewrite complex /= into l = l op r. + * everywhere, rewrite integer/complex /= into l = l op r. * TODO(rsc): Maybe this rewrite should be done always? */ et = n->left->type->etype; @@ -780,7 +909,8 @@ walkexpr(Node **np, NodeList **init) (thechar == '8' && isfloat[et]) || l->op == OINDEXMAP || et == TSTRING || - (iscomplex[et] && n->etype == ODIV)) { + (!isfloat[et] && n->etype == ODIV) || + n->etype == OMOD) { l = safeexpr(n->left, init); a = l; if(a->op == OINDEXMAP) { @@ -794,15 +924,24 @@ walkexpr(Node **np, NodeList **init) typecheck(&r, Etop); walkexpr(&r, init); n = r; + goto ret; } + if(n->etype == OLSH || n->etype == ORSH) + goto shiftwalked; goto ret; case OANDNOT: walkexpr(&n->left, init); - walkexpr(&n->right, init); n->op = OAND; n->right = nod(OCOM, n->right, N); typecheck(&n->right, Erv); + walkexpr(&n->right, init); + goto ret; + + case OMUL: + walkexpr(&n->left, init); + walkexpr(&n->right, init); + walkmul(&n, init); goto ret; case ODIV: @@ -821,63 +960,80 @@ walkexpr(Node **np, NodeList **init) n = conv(n, t); goto ret; } + // Nothing to do for float divisions. + if(isfloat[et]) + goto ret; + + // Try rewriting as shifts or magic multiplies. + walkdiv(&n, init); + /* - * rewrite div and mod into function calls + * rewrite 64-bit div and mod into function calls * on 32-bit architectures. */ - if(widthptr > 4 || (et != TUINT64 && et != TINT64)) - goto ret; - if(et == TINT64) - strcpy(namebuf, "int64"); - else - strcpy(namebuf, "uint64"); - if(n->op == ODIV) - strcat(namebuf, "div"); - else - strcat(namebuf, "mod"); - n = mkcall(namebuf, n->type, init, - conv(n->left, types[et]), conv(n->right, types[et])); + switch(n->op) { + case OMOD: + case ODIV: + if(widthptr > 4 || (et != TUINT64 && et != TINT64)) + goto ret; + if(et == TINT64) + strcpy(namebuf, "int64"); + else + strcpy(namebuf, "uint64"); + if(n->op == ODIV) + strcat(namebuf, "div"); + else + strcat(namebuf, "mod"); + n = mkcall(namebuf, n->type, init, + conv(n->left, types[et]), conv(n->right, types[et])); + break; + default: + break; + } goto ret; case OINDEX: walkexpr(&n->left, init); + // save the original node for bounds checking elision. + // If it was a ODIV/OMOD walk might rewrite it. + r = n->right; walkexpr(&n->right, init); // if range of type cannot exceed static array bound, - // disable bounds check - if(isfixedarray(n->left->type)) - if(!issigned[n->right->type->etype]) - if(n->right->type->width < 4) - if((1<<(8*n->right->type->width)) <= n->left->type->bound) - n->etype = 1; - - if(isconst(n->left, CTSTR)) - if(!issigned[n->right->type->etype]) - if(n->right->type->width < 4) - if((1<<(8*n->right->type->width)) <= n->left->val.u.sval->len) - n->etype = 1; - - // check for static out of bounds - if(isconst(n->right, CTINT) && !n->etype) { - v = mpgetfix(n->right->val.u.xval); - len = 1LL<<60; - t = n->left->type; - if(isconst(n->left, CTSTR)) - len = n->left->val.u.sval->len; - if(t != T && isptr[t->etype]) - t = t->type; - if(isfixedarray(t)) - len = t->bound; - if(v < 0 || v >= (1LL<<31) || v >= len) + // disable bounds check. + if(n->bounded) + goto ret; + t = n->left->type; + if(t != T && isptr[t->etype]) + t = t->type; + if(isfixedarray(t)) { + n->bounded = bounded(r, t->bound); + if(debug['m'] && n->bounded && !isconst(n->right, CTINT)) + warn("index bounds check elided"); + if(smallintconst(n->right) && !n->bounded) yyerror("index out of bounds"); - else if(isconst(n->left, CTSTR)) { - // replace "abc"[2] with 'b'. - // delayed until now because "abc"[2] is not - // an ideal constant. - nodconst(n, n->type, n->left->val.u.sval->s[v]); - n->typecheck = 1; + } else if(isconst(n->left, CTSTR)) { + n->bounded = bounded(r, n->left->val.u.sval->len); + if(debug['m'] && n->bounded && !isconst(n->right, CTINT)) + warn("index bounds check elided"); + if(smallintconst(n->right)) { + if(!n->bounded) + yyerror("index out of bounds"); + else { + // replace "abc"[2] with 'b'. + // delayed until now because "abc"[2] is not + // an ideal constant. + v = mpgetfix(n->right->val.u.xval); + nodconst(n, n->type, n->left->val.u.sval->s[v]); + n->typecheck = 1; + } } } + + if(isconst(n->right, CTINT)) + if(mpcmpfixfix(n->right->val.u.xval, &mpzero) < 0 || + mpcmpfixfix(n->right->val.u.xval, maxintval[TINT]) > 0) + yyerror("index out of bounds"); goto ret; case OINDEXMAP: @@ -895,95 +1051,29 @@ walkexpr(Node **np, NodeList **init) goto ret; case OSLICE: + if(n->right != N && n->right->left == N && n->right->right == N) { // noop + walkexpr(&n->left, init); + n = n->left; + goto ret; + } + // fallthrough case OSLICEARR: + case OSLICESTR: + if(n->right == N) // already processed + goto ret; + walkexpr(&n->left, init); - n->left = safeexpr(n->left, init); + // cgen_slice can't handle string literals as source + // TODO the OINDEX case is a bug elsewhere that needs to be traced. it causes a crash on ([2][]int{ ... })[1][lo:hi] + if((n->op == OSLICESTR && n->left->op == OLITERAL) || (n->left->op == OINDEX)) + n->left = copyexpr(n->left, n->left->type, init); + else + n->left = safeexpr(n->left, init); walkexpr(&n->right->left, init); n->right->left = safeexpr(n->right->left, init); walkexpr(&n->right->right, init); n->right->right = safeexpr(n->right->right, init); - - len = 1LL<<60; - t = n->left->type; - if(t != T && isptr[t->etype]) - t = t->type; - if(isfixedarray(t)) - len = t->bound; - - // check for static out of bounds - // NOTE: v > len not v >= len. - v1 = -1; - v2 = -1; - if(isconst(n->right->left, CTINT)) { - v1 = mpgetfix(n->right->left->val.u.xval); - if(v1 < 0 || v1 >= (1LL<<31) || v1 > len) { - yyerror("slice index out of bounds"); - v1 = -1; - } - } - if(isconst(n->right->right, CTINT)) { - v2 = mpgetfix(n->right->right->val.u.xval); - if(v2 < 0 || v2 >= (1LL<<31) || v2 > len) { - yyerror("slice index out of bounds"); - v2 = -1; - } - } - if(v1 >= 0 && v2 >= 0 && v1 > v2) - yyerror("inverted slice range"); - - if(n->op == OSLICEARR) - goto slicearray; - - // dynamic slice - // sliceslice(old []any, lb uint64, hb uint64, width uint64) (ary []any) - // sliceslice1(old []any, lb uint64, width uint64) (ary []any) - t = n->type; - et = n->etype; - if(n->right->left == N) - l = nodintconst(0); - else - l = conv(n->right->left, types[TUINT64]); - if(n->right->right != N) { - fn = syslook("sliceslice", 1); - argtype(fn, t->type); // any-1 - argtype(fn, t->type); // any-2 - n = mkcall1(fn, t, init, - n->left, - l, - conv(n->right->right, types[TUINT64]), - nodintconst(t->type->width)); - } else { - fn = syslook("sliceslice1", 1); - argtype(fn, t->type); // any-1 - argtype(fn, t->type); // any-2 - n = mkcall1(fn, t, init, - n->left, - l, - nodintconst(t->type->width)); - } - n->etype = et; // preserve no-typecheck flag from OSLICE to the slice* call. - goto ret; - - slicearray: - // static slice - // slicearray(old *any, uint64 nel, lb uint64, hb uint64, width uint64) (ary []any) - t = n->type; - fn = syslook("slicearray", 1); - argtype(fn, n->left->type->type); // any-1 - argtype(fn, t->type); // any-2 - if(n->right->left == N) - l = nodintconst(0); - else - l = conv(n->right->left, types[TUINT64]); - if(n->right->right == N) - r = nodintconst(n->left->type->type->bound); - else - r = conv(n->right->right, types[TUINT64]); - n = mkcall1(fn, t, init, - n->left, nodintconst(n->left->type->type->bound), - l, - r, - nodintconst(t->type->width)); + n = sliceany(n, init); // chops n->right, sets n->list goto ret; case OADDR: @@ -1031,27 +1121,34 @@ walkexpr(Node **np, NodeList **init) goto ret; } - // prepare for rewrite below if(n->etype == OEQ || n->etype == ONE) { + // prepare for rewrite below n->left = cheapexpr(n->left, init); n->right = cheapexpr(n->right, init); - } - // sys_cmpstring(s1, s2) :: 0 - r = mkcall("cmpstring", types[TINT], init, - conv(n->left, types[TSTRING]), - conv(n->right, types[TSTRING])); - r = nod(n->etype, r, nodintconst(0)); + r = mkcall("eqstring", types[TBOOL], init, + conv(n->left, types[TSTRING]), + conv(n->right, types[TSTRING])); - // quick check of len before full compare for == or != - if(n->etype == OEQ || n->etype == ONE) { - if(n->etype == OEQ) + // quick check of len before full compare for == or != + if(n->etype == OEQ) { + // len(left) == len(right) && eqstring(left, right) r = nod(OANDAND, nod(OEQ, nod(OLEN, n->left, N), nod(OLEN, n->right, N)), r); - else + } else { + // len(left) != len(right) || !eqstring(left, right) + r = nod(ONOT, r, N); r = nod(OOROR, nod(ONE, nod(OLEN, n->left, N), nod(OLEN, n->right, N)), r); + } typecheck(&r, Erv); walkexpr(&r, nil); + } else { + // sys_cmpstring(s1, s2) :: 0 + r = mkcall("cmpstring", types[TINT], init, + conv(n->left, types[TSTRING]), + conv(n->right, types[TSTRING])); + r = nod(n->etype, r, nodintconst(0)); } + typecheck(&r, Erv); if(n->type->etype != TBOOL) fatal("cmp %T", n->type); r->type = n->type; @@ -1061,25 +1158,7 @@ walkexpr(Node **np, NodeList **init) case OADDSTR: n = addstr(n, init); goto ret; - - case OSLICESTR: - // sys_slicestring(s, lb, hb) - if(n->right->left == N) - l = nodintconst(0); - else - l = conv(n->right->left, types[TINT]); - if(n->right->right) { - n = mkcall("slicestring", n->type, init, - conv(n->left, types[TSTRING]), - l, - conv(n->right->right, types[TINT])); - } else { - n = mkcall("slicestring1", n->type, init, - conv(n->left, types[TSTRING]), - l); - } - goto ret; - + case OAPPEND: if(n->isddd) { if(istype(n->type->type, TUINT8) && istype(n->list->next->n->type, TSTRING)) @@ -1177,6 +1256,9 @@ walkexpr(Node **np, NodeList **init) fn = syslook("efaceeq", 1); else fn = syslook("ifaceeq", 1); + + n->right = cheapexpr(n->right, init); + n->left = cheapexpr(n->left, init); argtype(fn, n->right->type); argtype(fn, n->left->type); r = mkcall1(fn, n->type, init, n->left, n->right); @@ -1189,7 +1271,7 @@ walkexpr(Node **np, NodeList **init) else r = nod(OOROR, nod(ONE, nod(OITAB, n->left, N), nod(OITAB, n->right, N)), r); typecheck(&r, Erv); - walkexpr(&r, nil); + walkexpr(&r, init); r->type = n->type; n = r; goto ret; @@ -1226,9 +1308,16 @@ ret: static Node* ascompatee1(int op, Node *l, Node *r, NodeList **init) { + Node *n; USED(op); + + // convas will turn map assigns into function calls, + // making it impossible for reorder3 to work. + n = nod(OAS, l, r); + if(l->op == OINDEXMAP) + return n; - return convas(nod(OAS, l, r), init); + return convas(n, init); } static NodeList* @@ -1249,12 +1338,16 @@ ascompatee(int op, NodeList *nl, NodeList *nr, NodeList **init) lr->n = safeexpr(lr->n, init); nn = nil; - for(ll=nl, lr=nr; ll && lr; ll=ll->next, lr=lr->next) + for(ll=nl, lr=nr; ll && lr; ll=ll->next, lr=lr->next) { + // Do not generate 'x = x' during return. See issue 4014. + if(op == ORETURN && ll->n == lr->n) + continue; nn = list(nn, ascompatee1(op, ll->n, lr->n, init)); + } // cannot happen: caller checked that lists had same length if(ll || lr) - yyerror("error in shape across %+H %O %+H", nl, op, nr); + yyerror("error in shape across %+H %O %+H / %d %d [%s]", nl, op, nr, count(nl), count(nr), curfn->nname->sym->name); return nn; } @@ -1826,13 +1919,14 @@ static int aliased(Node*, NodeList*, NodeList*); static NodeList* reorder3(NodeList *all) { - NodeList *list, *early; + NodeList *list, *early, *mapinit; Node *l; // If a needed expression may be affected by an // earlier assignment, make an early copy of that // expression and use the copy instead. early = nil; + mapinit = nil; for(list=all; list; list=list->next) { l = list->n->left; @@ -1856,8 +1950,11 @@ reorder3(NodeList *all) case ONAME: break; case OINDEX: + case OINDEXMAP: reorder3save(&l->left, all, list, &early); reorder3save(&l->right, all, list, &early); + if(l->op == OINDEXMAP) + list->n = convas(list->n, &mapinit); break; case OIND: case ODOTPTR: @@ -1868,6 +1965,7 @@ reorder3(NodeList *all) reorder3save(&list->n->right, all, list, &early); } + early = concat(mapinit, early); return concat(early, all); } @@ -2119,6 +2217,8 @@ paramstoheap(Type **argin, int out) nn = nil; for(t = structfirst(&savet, argin); t != T; t = structnext(&savet)) { v = t->nname; + if(v && v->sym && v->sym->name[0] == '~') + v = N; if(v == N && out && hasdefer) { // Defer might stop a panic and show the // return values as they exist at the time of panic. @@ -2395,12 +2495,12 @@ append(Node *n, NodeList **init) l = list(l, nod(OAS, nn, nod(OLEN, ns, N))); // n = len(s) nx = nod(OSLICE, ns, nod(OKEY, N, nod(OADD, nn, na))); // ...s[:n+argc] - nx->etype = 1; // disable bounds check + nx->bounded = 1; l = list(l, nod(OAS, ns, nx)); // s = s[:n+argc] for (a = n->list->next; a != nil; a = a->next) { nx = nod(OINDEX, ns, nn); // s[n] ... - nx->etype = 1; // disable bounds check + nx->bounded = 1; l = list(l, nod(OAS, nx, a->n)); // s[n] = arg if (a->next != nil) l = list(l, nod(OAS, nn, nod(OADD, nn, nodintconst(1)))); // n = n + 1 @@ -2412,6 +2512,151 @@ append(Node *n, NodeList **init) return ns; } + +// Generate frontend part for OSLICE[ARR|STR] +// +static Node* +sliceany(Node* n, NodeList **init) +{ + int bounded; + Node *src, *lb, *hb, *bound, *chk, *chk1, *chk2; + int64 lbv, hbv, bv, w; + Type *bt; + +// print("before sliceany: %+N\n", n); + + src = n->left; + lb = n->right->left; + hb = n->right->right; + + bounded = n->etype; + + if(n->op == OSLICESTR) + bound = nod(OLEN, src, N); + else + bound = nod(OCAP, src, N); + + typecheck(&bound, Erv); + walkexpr(&bound, init); // if src is an array, bound will be a const now. + + // static checks if possible + bv = 1LL<<50; + if(isconst(bound, CTINT)) { + if(!smallintconst(bound)) + yyerror("array len too large"); + else + bv = mpgetfix(bound->val.u.xval); + } + + if(isconst(hb, CTINT)) { + hbv = mpgetfix(hb->val.u.xval); + if(hbv < 0 || hbv > bv) { + yyerror("slice index out of bounds"); + hbv = -1; + } + } + if(isconst(lb, CTINT)) { + lbv = mpgetfix(lb->val.u.xval); + if(lbv < 0 || lbv > bv) { + yyerror("slice index out of bounds"); + lbv = -1; + } + if(lbv == 0) + lb = N; + } + + // dynamic checks convert all bounds to unsigned to save us the bound < 0 comparison + // generate + // if hb > bound || lb > hb { panicslice() } + chk = N; + chk1 = N; + chk2 = N; + + bt = types[simtype[TUINT]]; + if(hb != N && hb->type->width > 4) + bt = types[TUINT64]; + if(lb != N && lb->type->width > 4) + bt = types[TUINT64]; + + bound = cheapexpr(conv(bound, bt), init); + + if(hb != N) { + hb = cheapexpr(conv(hb, bt), init); + if(!bounded) + chk1 = nod(OLT, bound, hb); + } else if(n->op == OSLICEARR) { + hb = bound; + } else { + hb = nod(OLEN, src, N); + typecheck(&hb, Erv); + walkexpr(&hb, init); + hb = cheapexpr(conv(hb, bt), init); + } + + if(lb != N) { + lb = cheapexpr(conv(lb, bt), init); + if(!bounded) + chk2 = nod(OLT, hb, lb); + } + + if(chk1 != N || chk2 != N) { + chk = nod(OIF, N, N); + chk->nbody = list1(mkcall("panicslice", T, init)); + if(chk1 != N) + chk->ntest = chk1; + if(chk2 != N) { + if(chk->ntest == N) + chk->ntest = chk2; + else + chk->ntest = nod(OOROR, chk->ntest, chk2); + } + typecheck(&chk, Etop); + walkstmt(&chk); + *init = concat(*init, chk->ninit); + chk->ninit = nil; + *init = list(*init, chk); + } + + // prepare new cap, len and offs for backend cgen_slice + // cap = bound [ - lo ] + n->right = N; + n->list = nil; + if(lb == N) + bound = conv(bound, types[simtype[TUINT]]); + else + bound = nod(OSUB, conv(bound, types[simtype[TUINT]]), conv(lb, types[simtype[TUINT]])); + typecheck(&bound, Erv); + walkexpr(&bound, init); + n->list = list(n->list, bound); + + // len = hi [ - lo] + if(lb == N) + hb = conv(hb, types[simtype[TUINT]]); + else + hb = nod(OSUB, conv(hb, types[simtype[TUINT]]), conv(lb, types[simtype[TUINT]])); + typecheck(&hb, Erv); + walkexpr(&hb, init); + n->list = list(n->list, hb); + + // offs = [width *] lo, but omit if zero + if(lb != N) { + if(n->op == OSLICESTR) + w = 1; + else + w = n->type->type->width; + lb = conv(lb, types[TUINTPTR]); + if(w > 1) + lb = nod(OMUL, nodintconst(w), lb); + typecheck(&lb, Erv); + walkexpr(&lb, init); + n->list = list(n->list, lb); + } + +// print("after sliceany: %+N\n", n); + + return n; +} + static Node* eqfor(Type *t) { @@ -2531,6 +2776,8 @@ walkcompare(Node **np, NodeList **init) // Struct of four or fewer fields. // Inline comparisons. for(t1=t->type; t1; t1=t1->down) { + if(isblanksym(t1->sym)) + continue; li = nod(OXDOT, l, newname(t1->sym)); ri = nod(OXDOT, r, newname(t1->sym)); a = nod(n->op, li, ri); @@ -2596,3 +2843,591 @@ hard: *np = r; return; } + +static int +samecheap(Node *a, Node *b) +{ + if(a == N || b == N || a->op != b->op) + return 0; + + switch(a->op) { + case ONAME: + return a == b; + // TODO: Could do more here, but maybe this is enough. + // It's all cheapexpr does. + } + return 0; +} + +static void +walkrotate(Node **np) +{ + int w, sl, sr, s; + Node *l, *r; + Node *n; + + n = *np; + + // Want << | >> or >> | << or << ^ >> or >> ^ << on unsigned value. + l = n->left; + r = n->right; + if((n->op != OOR && n->op != OXOR) || + (l->op != OLSH && l->op != ORSH) || + (r->op != OLSH && r->op != ORSH) || + n->type == T || issigned[n->type->etype] || + l->op == r->op) { + return; + } + + // Want same, side effect-free expression on lhs of both shifts. + if(!samecheap(l->left, r->left)) + return; + + // Constants adding to width? + w = l->type->width * 8; + if(smallintconst(l->right) && smallintconst(r->right)) { + if((sl=mpgetfix(l->right->val.u.xval)) >= 0 && (sr=mpgetfix(r->right->val.u.xval)) >= 0 && sl+sr == w) + goto yes; + return; + } + + // TODO: Could allow s and 32-s if s is bounded (maybe s&31 and 32-s&31). + return; + +yes: + // Rewrite left shift half to left rotate. + if(l->op == OLSH) + n = l; + else + n = r; + n->op = OLROT; + + // Remove rotate 0 and rotate w. + s = mpgetfix(n->right->val.u.xval); + if(s == 0 || s == w) + n = n->left; + + *np = n; + return; +} + +/* + * walkmul rewrites integer multiplication by powers of two as shifts. + */ +static void +walkmul(Node **np, NodeList **init) +{ + Node *n, *nl, *nr; + int pow, neg, w; + + n = *np; + if(!isint[n->type->etype]) + return; + + if(n->right->op == OLITERAL) { + nl = n->left; + nr = n->right; + } else if(n->left->op == OLITERAL) { + nl = n->right; + nr = n->left; + } else + return; + + neg = 0; + + // x*0 is 0 (and side effects of x). + if(mpgetfix(nr->val.u.xval) == 0) { + cheapexpr(nl, init); + nodconst(n, n->type, 0); + goto ret; + } + + // nr is a constant. + pow = powtwo(nr); + if(pow < 0) + return; + if(pow >= 1000) { + // negative power of 2, like -16 + neg = 1; + pow -= 1000; + } + + w = nl->type->width*8; + if(pow+1 >= w)// too big, shouldn't happen + return; + + nl = cheapexpr(nl, init); + + if(pow == 0) { + // x*1 is x + n = nl; + goto ret; + } + + n = nod(OLSH, nl, nodintconst(pow)); + +ret: + if(neg) + n = nod(OMINUS, n, N); + + typecheck(&n, Erv); + walkexpr(&n, init); + *np = n; +} + +/* + * walkdiv rewrites division by a constant as less expensive + * operations. + */ +static void +walkdiv(Node **np, NodeList **init) +{ + Node *n, *nl, *nr, *nc; + Node *n1, *n2, *n3, *n4; + int pow; // if >= 0, nr is 1<<pow + int s; // 1 if nr is negative. + int w; + Type *twide; + Magic m; + + n = *np; + if(n->right->op != OLITERAL) + return; + // nr is a constant. + nl = cheapexpr(n->left, init); + nr = n->right; + + // special cases of mod/div + // by a constant + w = nl->type->width*8; + s = 0; + pow = powtwo(nr); + if(pow >= 1000) { + // negative power of 2 + s = 1; + pow -= 1000; + } + + if(pow+1 >= w) { + // divisor too large. + return; + } + if(pow < 0) { + goto divbymul; + } + + switch(pow) { + case 0: + if(n->op == OMOD) { + // nl % 1 is zero. + nodconst(n, n->type, 0); + } else if(s) { + // divide by -1 + n->op = OMINUS; + n->right = N; + } else { + // divide by 1 + n = nl; + } + break; + default: + if(issigned[n->type->etype]) { + if(n->op == OMOD) { + // signed modulo 2^pow is like ANDing + // with the last pow bits, but if nl < 0, + // nl & (2^pow-1) is (nl+1)%2^pow - 1. + nc = nod(OXXX, N, N); + nodconst(nc, types[simtype[TUINT]], w-1); + n1 = nod(ORSH, nl, nc); // n1 = -1 iff nl < 0. + if(pow == 1) { + typecheck(&n1, Erv); + n1 = cheapexpr(n1, init); + // n = (nl+ε)&1 -ε where ε=1 iff nl<0. + n2 = nod(OSUB, nl, n1); + nc = nod(OXXX, N, N); + nodconst(nc, nl->type, 1); + n3 = nod(OAND, n2, nc); + n = nod(OADD, n3, n1); + } else { + // n = (nl+ε)&(nr-1) - ε where ε=2^pow-1 iff nl<0. + nc = nod(OXXX, N, N); + nodconst(nc, nl->type, (1LL<<pow)-1); + n2 = nod(OAND, n1, nc); // n2 = 2^pow-1 iff nl<0. + typecheck(&n2, Erv); + n2 = cheapexpr(n2, init); + + n3 = nod(OADD, nl, n2); + n4 = nod(OAND, n3, nc); + n = nod(OSUB, n4, n2); + } + break; + } else { + // arithmetic right shift does not give the correct rounding. + // if nl >= 0, nl >> n == nl / nr + // if nl < 0, we want to add 2^n-1 first. + nc = nod(OXXX, N, N); + nodconst(nc, types[simtype[TUINT]], w-1); + n1 = nod(ORSH, nl, nc); // n1 = -1 iff nl < 0. + if(pow == 1) { + // nl+1 is nl-(-1) + n->left = nod(OSUB, nl, n1); + } else { + // Do a logical right right on -1 to keep pow bits. + nc = nod(OXXX, N, N); + nodconst(nc, types[simtype[TUINT]], w-pow); + n2 = nod(ORSH, conv(n1, tounsigned(nl->type)), nc); + n->left = nod(OADD, nl, conv(n2, nl->type)); + } + // n = (nl + 2^pow-1) >> pow + n->op = ORSH; + nc = nod(OXXX, N, N); + nodconst(nc, types[simtype[TUINT]], pow); + n->right = nc; + n->typecheck = 0; + } + if(s) + n = nod(OMINUS, n, N); + break; + } + nc = nod(OXXX, N, N); + if(n->op == OMOD) { + // n = nl & (nr-1) + n->op = OAND; + nodconst(nc, nl->type, mpgetfix(nr->val.u.xval)-1); + } else { + // n = nl >> pow + n->op = ORSH; + nodconst(nc, types[simtype[TUINT]], pow); + } + n->typecheck = 0; + n->right = nc; + break; + } + goto ret; + +divbymul: + // try to do division by multiply by (2^w)/d + // see hacker's delight chapter 10 + // TODO: support 64-bit magic multiply here. + m.w = w; + if(issigned[nl->type->etype]) { + m.sd = mpgetfix(nr->val.u.xval); + smagic(&m); + } else { + m.ud = mpgetfix(nr->val.u.xval); + umagic(&m); + } + if(m.bad) + return; + + // We have a quick division method so use it + // for modulo too. + if(n->op == OMOD) + goto longmod; + + switch(simtype[nl->type->etype]) { + default: + return; + + case TUINT8: + case TUINT16: + case TUINT32: + // n1 = nl * magic >> w (HMUL) + nc = nod(OXXX, N, N); + nodconst(nc, nl->type, m.um); + n1 = nod(OMUL, nl, nc); + typecheck(&n1, Erv); + n1->op = OHMUL; + if(m.ua) { + // Select a Go type with (at least) twice the width. + switch(simtype[nl->type->etype]) { + default: + return; + case TUINT8: + case TUINT16: + twide = types[TUINT32]; + break; + case TUINT32: + twide = types[TUINT64]; + break; + case TINT8: + case TINT16: + twide = types[TINT32]; + break; + case TINT32: + twide = types[TINT64]; + break; + } + + // add numerator (might overflow). + // n2 = (n1 + nl) + n2 = nod(OADD, conv(n1, twide), conv(nl, twide)); + + // shift by m.s + nc = nod(OXXX, N, N); + nodconst(nc, types[TUINT], m.s); + n = conv(nod(ORSH, n2, nc), nl->type); + } else { + // n = n1 >> m.s + nc = nod(OXXX, N, N); + nodconst(nc, types[TUINT], m.s); + n = nod(ORSH, n1, nc); + } + break; + + case TINT8: + case TINT16: + case TINT32: + // n1 = nl * magic >> w + nc = nod(OXXX, N, N); + nodconst(nc, nl->type, m.sm); + n1 = nod(OMUL, nl, nc); + typecheck(&n1, Erv); + n1->op = OHMUL; + if(m.sm < 0) { + // add the numerator. + n1 = nod(OADD, n1, nl); + } + // shift by m.s + nc = nod(OXXX, N, N); + nodconst(nc, types[TUINT], m.s); + n2 = conv(nod(ORSH, n1, nc), nl->type); + // add 1 iff n1 is negative. + nc = nod(OXXX, N, N); + nodconst(nc, types[TUINT], w-1); + n3 = nod(ORSH, nl, nc); // n4 = -1 iff n1 is negative. + n = nod(OSUB, n2, n3); + // apply sign. + if(m.sd < 0) + n = nod(OMINUS, n, N); + break; + } + goto ret; + +longmod: + // rewrite as A%B = A - (A/B*B). + n1 = nod(ODIV, nl, nr); + n2 = nod(OMUL, n1, nr); + n = nod(OSUB, nl, n2); + goto ret; + +ret: + typecheck(&n, Erv); + walkexpr(&n, init); + *np = n; +} + +// return 1 if integer n must be in range [0, max), 0 otherwise +static int +bounded(Node *n, int64 max) +{ + int64 v; + int32 bits; + int sign; + + if(n->type == T || !isint[n->type->etype]) + return 0; + + sign = issigned[n->type->etype]; + bits = 8*n->type->width; + + if(smallintconst(n)) { + v = mpgetfix(n->val.u.xval); + return 0 <= v && v < max; + } + + switch(n->op) { + case OAND: + v = -1; + if(smallintconst(n->left)) { + v = mpgetfix(n->left->val.u.xval); + } else if(smallintconst(n->right)) { + v = mpgetfix(n->right->val.u.xval); + } + if(0 <= v && v < max) + return 1; + break; + + case OMOD: + if(!sign && smallintconst(n->right)) { + v = mpgetfix(n->right->val.u.xval); + if(0 <= v && v <= max) + return 1; + } + break; + + case ODIV: + if(!sign && smallintconst(n->right)) { + v = mpgetfix(n->right->val.u.xval); + while(bits > 0 && v >= 2) { + bits--; + v >>= 1; + } + } + break; + + case ORSH: + if(!sign && smallintconst(n->right)) { + v = mpgetfix(n->right->val.u.xval); + if(v > bits) + return 1; + bits -= v; + } + break; + } + + if(!sign && bits <= 62 && (1LL<<bits) <= max) + return 1; + + return 0; +} + +void +usefield(Node *n) +{ + Type *field, *l; + + if(!fieldtrack_enabled) + return; + + switch(n->op) { + default: + fatal("usefield %O", n->op); + case ODOT: + case ODOTPTR: + break; + } + + field = n->paramfld; + if(field == T) + fatal("usefield %T %S without paramfld", n->left->type, n->right->sym); + if(field->note == nil || strstr(field->note->s, "go:\"track\"") == nil) + return; + + // dedup on list + if(field->lastfn == curfn) + return; + field->lastfn = curfn; + field->outer = n->left->type; + if(isptr[field->outer->etype]) + field->outer = field->outer->type; + if(field->outer->sym == S) + yyerror("tracked field must be in named struct type"); + if(!exportname(field->sym->name)) + yyerror("tracked field must be exported (upper case)"); + + l = typ(0); + l->type = field; + l->down = curfn->paramfld; + curfn->paramfld = l; +} + +static int +candiscardlist(NodeList *l) +{ + for(; l; l=l->next) + if(!candiscard(l->n)) + return 0; + return 1; +} + +int +candiscard(Node *n) +{ + if(n == N) + return 1; + + switch(n->op) { + default: + return 0; + + case ONAME: + case ONONAME: + case OTYPE: + case OPACK: + case OLITERAL: + case OADD: + case OSUB: + case OOR: + case OXOR: + case OADDSTR: + case OADDR: + case OANDAND: + case OARRAYBYTESTR: + case OARRAYRUNESTR: + case OSTRARRAYBYTE: + case OSTRARRAYRUNE: + case OCAP: + case OCMPIFACE: + case OCMPSTR: + case OCOMPLIT: + case OMAPLIT: + case OSTRUCTLIT: + case OARRAYLIT: + case OPTRLIT: + case OCONV: + case OCONVIFACE: + case OCONVNOP: + case ODOT: + case OEQ: + case ONE: + case OLT: + case OLE: + case OGT: + case OGE: + case OKEY: + case OLEN: + case OMUL: + case OLSH: + case ORSH: + case OAND: + case OANDNOT: + case ONEW: + case ONOT: + case OCOM: + case OPLUS: + case OMINUS: + case OOROR: + case OPAREN: + case ORUNESTR: + case OREAL: + case OIMAG: + case OCOMPLEX: + // Discardable as long as the subpieces are. + break; + + case ODIV: + case OMOD: + // Discardable as long as we know it's not division by zero. + if(isconst(n->right, CTINT) && mpcmpfixc(n->right->val.u.xval, 0) != 0) + break; + if(isconst(n->right, CTFLT) && mpcmpfltc(n->right->val.u.fval, 0) != 0) + break; + return 0; + + case OMAKECHAN: + case OMAKEMAP: + // Discardable as long as we know it won't fail because of a bad size. + if(isconst(n->left, CTINT) && mpcmpfixc(n->left->val.u.xval, 0) == 0) + break; + return 0; + + case OMAKESLICE: + // Difficult to tell what sizes are okay. + return 0; + } + + if(!candiscard(n->left) || + !candiscard(n->right) || + !candiscard(n->ntest) || + !candiscard(n->nincr) || + !candiscardlist(n->ninit) || + !candiscardlist(n->nbody) || + !candiscardlist(n->nelse) || + !candiscardlist(n->list) || + !candiscardlist(n->rlist)) { + return 0; + } + + return 1; +} diff --git a/src/cmd/gc/y.tab.c b/src/cmd/gc/y.tab.c index 97bf233eb..75175455e 100644 --- a/src/cmd/gc/y.tab.c +++ b/src/cmd/gc/y.tab.c @@ -1,21 +1,24 @@ -/* A Bison parser, made by GNU Bison 2.5. */ +/* A Bison parser, made by GNU Bison 2.3. */ -/* Bison implementation for Yacc-like parsers in C - - Copyright (C) 1984, 1989-1990, 2000-2011 Free Software Foundation, Inc. - - This program is free software: you can redistribute it and/or modify +/* Skeleton implementation for Bison's Yacc-like parsers in C + + Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 + Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - + the Free Software Foundation; either version 2, or (at your option) + any later version. + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. */ + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work @@ -26,7 +29,7 @@ special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. - + This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ @@ -44,7 +47,7 @@ #define YYBISON 1 /* Bison version. */ -#define YYBISON_VERSION "2.5" +#define YYBISON_VERSION "2.3" /* Skeleton name. */ #define YYSKELETON_NAME "yacc.c" @@ -52,52 +55,11 @@ /* Pure parsers. */ #define YYPURE 0 -/* Push parsers. */ -#define YYPUSH 0 - -/* Pull parsers. */ -#define YYPULL 1 - /* Using locations. */ #define YYLSP_NEEDED 0 -/* Copy the first part of user declarations. */ - -/* Line 268 of yacc.c */ -#line 20 "go.y" - -#include <u.h> -#include <stdio.h> /* if we don't, bison will, and go.h re-#defines getc */ -#include <libc.h> -#include "go.h" - -static void fixlbrace(int); - - -/* Line 268 of yacc.c */ -#line 81 "y.tab.c" - -/* Enabling traces. */ -#ifndef YYDEBUG -# define YYDEBUG 0 -#endif - -/* Enabling verbose error messages. */ -#ifdef YYERROR_VERBOSE -# undef YYERROR_VERBOSE -# define YYERROR_VERBOSE 1 -#else -# define YYERROR_VERBOSE 1 -#endif - -/* Enabling the token table. */ -#ifndef YYTOKEN_TABLE -# define YYTOKEN_TABLE 0 -#endif - - /* Tokens. */ #ifndef YYTOKENTYPE # define YYTOKENTYPE @@ -106,10 +68,10 @@ static void fixlbrace(int); enum yytokentype { LLITERAL = 258, LASOP = 259, - LBREAK = 260, - LCASE = 261, - LCHAN = 262, - LCOLAS = 263, + LCOLAS = 260, + LBREAK = 261, + LCASE = 262, + LCHAN = 263, LCONST = 264, LCONTINUE = 265, LDDD = 266, @@ -158,10 +120,10 @@ static void fixlbrace(int); /* Tokens. */ #define LLITERAL 258 #define LASOP 259 -#define LBREAK 260 -#define LCASE 261 -#define LCHAN 262 -#define LCOLAS 263 +#define LCOLAS 260 +#define LBREAK 261 +#define LCASE 262 +#define LCHAN 263 #define LCONST 264 #define LCONTINUE 265 #define LDDD 266 @@ -209,36 +171,61 @@ static void fixlbrace(int); +/* Copy the first part of user declarations. */ +#line 20 "go.y" + +#include <u.h> +#include <stdio.h> /* if we don't, bison will, and go.h re-#defines getc */ +#include <libc.h> +#include "go.h" + +static void fixlbrace(int); + + +/* Enabling traces. */ +#ifndef YYDEBUG +# define YYDEBUG 0 +#endif + +/* Enabling verbose error messages. */ +#ifdef YYERROR_VERBOSE +# undef YYERROR_VERBOSE +# define YYERROR_VERBOSE 1 +#else +# define YYERROR_VERBOSE 1 +#endif + +/* Enabling the token table. */ +#ifndef YYTOKEN_TABLE +# define YYTOKEN_TABLE 0 +#endif + #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED typedef union YYSTYPE -{ - -/* Line 293 of yacc.c */ #line 28 "go.y" - +{ Node* node; NodeList* list; Type* type; Sym* sym; struct Val val; int i; - - - -/* Line 293 of yacc.c */ -#line 230 "y.tab.c" -} YYSTYPE; -# define YYSTYPE_IS_TRIVIAL 1 +} +/* Line 193 of yacc.c. */ +#line 216 "y.tab.c" + YYSTYPE; # define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 +# define YYSTYPE_IS_TRIVIAL 1 #endif + /* Copy the second part of user declarations. */ -/* Line 343 of yacc.c */ -#line 242 "y.tab.c" +/* Line 216 of yacc.c. */ +#line 229 "y.tab.c" #ifdef short # undef short @@ -313,14 +300,14 @@ typedef short int yytype_int16; #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static int -YYID (int yyi) +YYID (int i) #else static int -YYID (yyi) - int yyi; +YYID (i) + int i; #endif { - return yyi; + return i; } #endif @@ -341,11 +328,11 @@ YYID (yyi) # define alloca _alloca # else # define YYSTACK_ALLOC alloca -# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ +# if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) # include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ -# ifndef EXIT_SUCCESS -# define EXIT_SUCCESS 0 +# ifndef _STDLIB_H +# define _STDLIB_H 1 # endif # endif # endif @@ -368,24 +355,24 @@ YYID (yyi) # ifndef YYSTACK_ALLOC_MAXIMUM # define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM # endif -# if (defined __cplusplus && ! defined EXIT_SUCCESS \ +# if (defined __cplusplus && ! defined _STDLIB_H \ && ! ((defined YYMALLOC || defined malloc) \ && (defined YYFREE || defined free))) # include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ -# ifndef EXIT_SUCCESS -# define EXIT_SUCCESS 0 +# ifndef _STDLIB_H +# define _STDLIB_H 1 # endif # endif # ifndef YYMALLOC # define YYMALLOC malloc -# if ! defined malloc && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ +# if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ # endif # endif # ifndef YYFREE # define YYFREE free -# if ! defined free && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ +# if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) void free (void *); /* INFRINGES ON USER NAME SPACE */ # endif @@ -401,9 +388,9 @@ void free (void *); /* INFRINGES ON USER NAME SPACE */ /* A type that is properly aligned for any stack member. */ union yyalloc { - yytype_int16 yyss_alloc; - YYSTYPE yyvs_alloc; -}; + yytype_int16 yyss; + YYSTYPE yyvs; + }; /* The size of the maximum gap between one aligned stack and the next. */ # define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) @@ -414,27 +401,6 @@ union yyalloc ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \ + YYSTACK_GAP_MAXIMUM) -# define YYCOPY_NEEDED 1 - -/* Relocate STACK from its old location to the new one. The - local variables YYSIZE and YYSTACKSIZE give the old and new number of - elements in the stack, and YYPTR gives the new location of the - stack. Advance YYPTR to a properly aligned location for the next - stack. */ -# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ - do \ - { \ - YYSIZE_T yynewbytes; \ - YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ - Stack = &yyptr->Stack_alloc; \ - yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ - yyptr += yynewbytes / sizeof (*yyptr); \ - } \ - while (YYID (0)) - -#endif - -#if defined YYCOPY_NEEDED && YYCOPY_NEEDED /* Copy COUNT objects from FROM to TO. The source and destination do not overlap. */ # ifndef YYCOPY @@ -452,21 +418,38 @@ union yyalloc while (YYID (0)) # endif # endif -#endif /* !YYCOPY_NEEDED */ + +/* Relocate STACK from its old location to the new one. The + local variables YYSIZE and YYSTACKSIZE give the old and new number of + elements in the stack, and YYPTR gives the new location of the + stack. Advance YYPTR to a properly aligned location for the next + stack. */ +# define YYSTACK_RELOCATE(Stack) \ + do \ + { \ + YYSIZE_T yynewbytes; \ + YYCOPY (&yyptr->Stack, Stack, yysize); \ + Stack = &yyptr->Stack; \ + yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ + yyptr += yynewbytes / sizeof (*yyptr); \ + } \ + while (YYID (0)) + +#endif /* YYFINAL -- State number of the termination state. */ #define YYFINAL 4 /* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 2131 +#define YYLAST 2194 /* YYNTOKENS -- Number of terminals. */ #define YYNTOKENS 76 /* YYNNTS -- Number of nonterminals. */ -#define YYNNTS 138 +#define YYNNTS 142 /* YYNRULES -- Number of rules. */ -#define YYNRULES 344 +#define YYNRULES 349 /* YYNRULES -- Number of states. */ -#define YYNSTATES 653 +#define YYNSTATES 663 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ #define YYUNDEFTOK 2 @@ -524,148 +507,150 @@ static const yytype_uint16 yyprhs[] = 162, 164, 168, 172, 176, 179, 182, 186, 192, 198, 201, 202, 207, 208, 212, 213, 216, 217, 222, 227, 232, 238, 240, 242, 245, 246, 250, 252, 256, 257, - 258, 259, 267, 268, 271, 274, 275, 276, 284, 285, - 291, 293, 297, 301, 305, 309, 313, 317, 321, 325, - 329, 333, 337, 341, 345, 349, 353, 357, 361, 365, - 369, 373, 375, 378, 381, 384, 387, 390, 393, 396, - 399, 403, 409, 416, 418, 420, 424, 430, 436, 441, - 448, 450, 455, 461, 467, 475, 477, 478, 482, 484, - 489, 491, 495, 497, 499, 501, 503, 505, 507, 509, - 510, 512, 514, 516, 518, 523, 525, 527, 529, 532, - 534, 536, 538, 540, 542, 546, 548, 550, 552, 555, - 557, 559, 561, 563, 567, 569, 571, 573, 575, 577, - 579, 581, 583, 585, 589, 594, 599, 602, 606, 612, - 614, 616, 619, 623, 629, 633, 639, 643, 647, 653, - 662, 668, 677, 683, 684, 688, 689, 691, 695, 697, - 702, 705, 706, 710, 712, 716, 718, 722, 724, 728, - 730, 734, 736, 740, 744, 747, 752, 756, 762, 768, - 770, 774, 776, 779, 781, 785, 790, 792, 795, 798, - 800, 802, 806, 807, 810, 811, 813, 815, 817, 819, - 821, 823, 825, 827, 829, 830, 835, 837, 840, 843, - 846, 849, 852, 855, 857, 861, 863, 867, 869, 873, - 875, 879, 881, 885, 887, 889, 893, 897, 898, 901, - 902, 904, 905, 907, 908, 910, 911, 913, 914, 916, - 917, 919, 920, 922, 923, 925, 926, 928, 933, 938, - 944, 951, 956, 961, 963, 965, 967, 969, 971, 973, - 975, 977, 979, 983, 988, 994, 999, 1004, 1007, 1010, - 1015, 1019, 1023, 1029, 1033, 1038, 1042, 1048, 1050, 1051, - 1053, 1057, 1059, 1061, 1064, 1066, 1068, 1074, 1075, 1078, - 1080, 1084, 1086, 1090, 1092 + 258, 259, 268, 269, 275, 276, 279, 280, 283, 284, + 285, 293, 294, 300, 302, 306, 310, 314, 318, 322, + 326, 330, 334, 338, 342, 346, 350, 354, 358, 362, + 366, 370, 374, 378, 382, 384, 387, 390, 393, 396, + 399, 402, 405, 408, 412, 418, 425, 427, 429, 433, + 439, 445, 450, 457, 459, 465, 471, 477, 485, 487, + 488, 492, 494, 499, 501, 506, 508, 512, 514, 516, + 518, 520, 522, 524, 526, 527, 529, 531, 533, 535, + 540, 542, 544, 546, 549, 551, 553, 555, 557, 559, + 563, 565, 567, 569, 572, 574, 576, 578, 580, 584, + 586, 588, 590, 592, 594, 596, 598, 600, 602, 606, + 611, 616, 619, 623, 629, 631, 633, 636, 640, 646, + 650, 656, 660, 664, 670, 679, 685, 694, 700, 701, + 705, 706, 708, 712, 714, 719, 722, 723, 727, 729, + 733, 735, 739, 741, 745, 747, 751, 753, 757, 761, + 764, 769, 773, 779, 785, 787, 791, 793, 796, 798, + 802, 807, 809, 812, 815, 817, 819, 823, 824, 827, + 828, 830, 832, 834, 836, 838, 840, 842, 844, 846, + 847, 852, 854, 857, 860, 863, 866, 869, 872, 874, + 878, 880, 884, 886, 890, 892, 896, 898, 902, 904, + 906, 910, 914, 915, 918, 919, 921, 922, 924, 925, + 927, 928, 930, 931, 933, 934, 936, 937, 939, 940, + 942, 943, 945, 950, 955, 961, 968, 973, 978, 980, + 982, 984, 986, 988, 990, 992, 994, 996, 1000, 1005, + 1011, 1016, 1021, 1024, 1027, 1032, 1036, 1040, 1046, 1050, + 1055, 1059, 1065, 1067, 1068, 1070, 1074, 1076, 1078, 1081, + 1083, 1085, 1091, 1092, 1095, 1097, 1101, 1103, 1107, 1109 }; /* YYRHS -- A `-1'-separated list of the rules' RHS. */ static const yytype_int16 yyrhs[] = { - 77, 0, -1, 79, 78, 81, 162, -1, -1, 25, - 137, 62, -1, -1, 80, 86, 88, -1, -1, 81, - 82, 62, -1, 21, 83, -1, 21, 59, 84, 186, + 77, 0, -1, 79, 78, 81, 166, -1, -1, 25, + 141, 62, -1, -1, 80, 86, 88, -1, -1, 81, + 82, 62, -1, 21, 83, -1, 21, 59, 84, 190, 60, -1, 21, 59, 60, -1, 85, 86, 88, -1, 85, 88, -1, 83, -1, 84, 62, 83, -1, 3, - -1, 137, 3, -1, 63, 3, -1, 25, 24, 87, - 62, -1, -1, 24, -1, -1, 89, 210, 64, 64, - -1, -1, 91, -1, 154, -1, 177, -1, 1, -1, - 32, 93, -1, 32, 59, 163, 186, 60, -1, 32, - 59, 60, -1, 92, 94, -1, 92, 59, 94, 186, - 60, -1, 92, 59, 94, 62, 164, 186, 60, -1, - 92, 59, 60, -1, 31, 97, -1, 31, 59, 165, - 186, 60, -1, 31, 59, 60, -1, 9, -1, 181, - 142, -1, 181, 142, 65, 182, -1, 181, 65, 182, - -1, 181, 142, 65, 182, -1, 181, 65, 182, -1, - 94, -1, 181, 142, -1, 181, -1, 137, -1, 96, - 142, -1, 123, -1, 123, 4, 123, -1, 182, 65, - 182, -1, 182, 8, 182, -1, 123, 42, -1, 123, - 37, -1, 6, 183, 66, -1, 6, 183, 65, 123, - 66, -1, 6, 183, 8, 123, 66, -1, 12, 66, - -1, -1, 67, 101, 179, 68, -1, -1, 99, 103, - 179, -1, -1, 104, 102, -1, -1, 35, 106, 179, - 68, -1, 182, 65, 26, 123, -1, 182, 8, 26, - 123, -1, 190, 62, 190, 62, 190, -1, 190, -1, + -1, 141, 3, -1, 63, 3, -1, 25, 24, 87, + 62, -1, -1, 24, -1, -1, 89, 214, 64, 64, + -1, -1, 91, -1, 158, -1, 181, -1, 1, -1, + 32, 93, -1, 32, 59, 167, 190, 60, -1, 32, + 59, 60, -1, 92, 94, -1, 92, 59, 94, 190, + 60, -1, 92, 59, 94, 62, 168, 190, 60, -1, + 92, 59, 60, -1, 31, 97, -1, 31, 59, 169, + 190, 60, -1, 31, 59, 60, -1, 9, -1, 185, + 146, -1, 185, 146, 65, 186, -1, 185, 65, 186, + -1, 185, 146, 65, 186, -1, 185, 65, 186, -1, + 94, -1, 185, 146, -1, 185, -1, 141, -1, 96, + 146, -1, 126, -1, 126, 4, 126, -1, 186, 65, + 186, -1, 186, 5, 186, -1, 126, 42, -1, 126, + 37, -1, 7, 187, 66, -1, 7, 187, 65, 126, + 66, -1, 7, 187, 5, 126, 66, -1, 12, 66, + -1, -1, 67, 101, 183, 68, -1, -1, 99, 103, + 183, -1, -1, 104, 102, -1, -1, 35, 106, 183, + 68, -1, 186, 65, 26, 126, -1, 186, 5, 26, + 126, -1, 194, 62, 194, 62, 194, -1, 194, -1, 107, -1, 108, 105, -1, -1, 16, 111, 109, -1, - 190, -1, 190, 62, 190, -1, -1, -1, -1, 20, - 114, 112, 115, 105, 116, 117, -1, -1, 14, 113, - -1, 14, 100, -1, -1, -1, 30, 119, 112, 120, - 35, 104, 68, -1, -1, 28, 122, 35, 104, 68, - -1, 124, -1, 123, 47, 123, -1, 123, 33, 123, - -1, 123, 38, 123, -1, 123, 46, 123, -1, 123, - 45, 123, -1, 123, 43, 123, -1, 123, 39, 123, - -1, 123, 40, 123, -1, 123, 49, 123, -1, 123, - 50, 123, -1, 123, 51, 123, -1, 123, 52, 123, - -1, 123, 53, 123, -1, 123, 54, 123, -1, 123, - 55, 123, -1, 123, 56, 123, -1, 123, 34, 123, - -1, 123, 44, 123, -1, 123, 48, 123, -1, 123, - 36, 123, -1, 130, -1, 53, 124, -1, 56, 124, - -1, 49, 124, -1, 50, 124, -1, 69, 124, -1, - 70, 124, -1, 52, 124, -1, 36, 124, -1, 130, - 59, 60, -1, 130, 59, 183, 187, 60, -1, 130, - 59, 183, 11, 187, 60, -1, 3, -1, 139, -1, - 130, 63, 137, -1, 130, 63, 59, 131, 60, -1, - 130, 63, 59, 31, 60, -1, 130, 71, 123, 72, - -1, 130, 71, 188, 66, 188, 72, -1, 125, -1, - 145, 59, 123, 60, -1, 146, 133, 127, 185, 68, - -1, 126, 67, 127, 185, 68, -1, 59, 131, 60, - 67, 127, 185, 68, -1, 161, -1, -1, 123, 66, - 129, -1, 123, -1, 67, 127, 185, 68, -1, 126, - -1, 59, 131, 60, -1, 123, -1, 143, -1, 142, - -1, 35, -1, 67, -1, 137, -1, 137, -1, -1, - 134, -1, 24, -1, 138, -1, 73, -1, 74, 3, - 63, 24, -1, 137, -1, 134, -1, 11, -1, 11, - 142, -1, 151, -1, 157, -1, 149, -1, 150, -1, - 148, -1, 59, 142, 60, -1, 151, -1, 157, -1, - 149, -1, 53, 143, -1, 157, -1, 149, -1, 150, - -1, 148, -1, 59, 142, 60, -1, 157, -1, 149, - -1, 149, -1, 151, -1, 157, -1, 149, -1, 150, - -1, 148, -1, 139, -1, 139, 63, 137, -1, 71, - 188, 72, 142, -1, 71, 11, 72, 142, -1, 7, - 144, -1, 7, 36, 142, -1, 23, 71, 142, 72, - 142, -1, 152, -1, 153, -1, 53, 142, -1, 36, - 7, 142, -1, 29, 133, 166, 186, 68, -1, 29, - 133, 68, -1, 22, 133, 167, 186, 68, -1, 22, - 133, 68, -1, 17, 155, 158, -1, 137, 59, 175, - 60, 159, -1, 59, 175, 60, 137, 59, 175, 60, - 159, -1, 196, 59, 191, 60, 206, -1, 59, 211, - 60, 137, 59, 191, 60, 206, -1, 17, 59, 175, - 60, 159, -1, -1, 67, 179, 68, -1, -1, 147, - -1, 59, 175, 60, -1, 157, -1, 160, 133, 179, - 68, -1, 160, 1, -1, -1, 162, 90, 62, -1, - 93, -1, 163, 62, 93, -1, 95, -1, 164, 62, - 95, -1, 97, -1, 165, 62, 97, -1, 168, -1, - 166, 62, 168, -1, 171, -1, 167, 62, 171, -1, - 180, 142, 194, -1, 170, 194, -1, 59, 170, 60, - 194, -1, 53, 170, 194, -1, 59, 53, 170, 60, - 194, -1, 53, 59, 170, 60, 194, -1, 24, -1, - 24, 63, 137, -1, 169, -1, 134, 172, -1, 169, - -1, 59, 169, 60, -1, 59, 175, 60, 159, -1, - 132, -1, 137, 132, -1, 137, 141, -1, 141, -1, - 173, -1, 174, 75, 173, -1, -1, 174, 187, -1, - -1, 100, -1, 91, -1, 177, -1, 1, -1, 98, - -1, 110, -1, 118, -1, 121, -1, 113, -1, -1, - 140, 66, 178, 176, -1, 15, -1, 5, 136, -1, - 10, 136, -1, 18, 125, -1, 13, 125, -1, 19, - 134, -1, 27, 189, -1, 176, -1, 179, 62, 176, - -1, 134, -1, 180, 75, 134, -1, 135, -1, 181, - 75, 135, -1, 123, -1, 182, 75, 123, -1, 131, - -1, 183, 75, 131, -1, 128, -1, 129, -1, 184, - 75, 128, -1, 184, 75, 129, -1, -1, 184, 187, - -1, -1, 62, -1, -1, 75, -1, -1, 123, -1, - -1, 182, -1, -1, 98, -1, -1, 211, -1, -1, - 212, -1, -1, 213, -1, -1, 3, -1, 21, 24, - 3, 62, -1, 32, 196, 198, 62, -1, 9, 196, - 65, 209, 62, -1, 9, 196, 198, 65, 209, 62, - -1, 31, 197, 198, 62, -1, 17, 156, 158, 62, - -1, 138, -1, 196, -1, 200, -1, 201, -1, 202, - -1, 200, -1, 202, -1, 138, -1, 24, -1, 71, - 72, 198, -1, 71, 3, 72, 198, -1, 23, 71, - 198, 72, 198, -1, 29, 67, 192, 68, -1, 22, - 67, 193, 68, -1, 53, 198, -1, 7, 199, -1, - 7, 59, 201, 60, -1, 7, 36, 198, -1, 36, - 7, 198, -1, 17, 59, 191, 60, 206, -1, 137, - 198, 194, -1, 137, 11, 198, 194, -1, 137, 198, - 194, -1, 137, 59, 191, 60, 206, -1, 198, -1, - -1, 207, -1, 59, 191, 60, -1, 198, -1, 3, - -1, 50, 3, -1, 137, -1, 208, -1, 59, 208, - 49, 208, 60, -1, -1, 210, 195, -1, 203, -1, - 211, 75, 203, -1, 204, -1, 212, 62, 204, -1, - 205, -1, 213, 62, 205, -1 + 194, -1, 194, 62, 194, -1, -1, -1, -1, 20, + 114, 112, 115, 105, 116, 119, 120, -1, -1, 14, + 20, 118, 112, 105, -1, -1, 119, 117, -1, -1, + 14, 100, -1, -1, -1, 30, 122, 112, 123, 35, + 104, 68, -1, -1, 28, 125, 35, 104, 68, -1, + 127, -1, 126, 47, 126, -1, 126, 33, 126, -1, + 126, 38, 126, -1, 126, 46, 126, -1, 126, 45, + 126, -1, 126, 43, 126, -1, 126, 39, 126, -1, + 126, 40, 126, -1, 126, 49, 126, -1, 126, 50, + 126, -1, 126, 51, 126, -1, 126, 52, 126, -1, + 126, 53, 126, -1, 126, 54, 126, -1, 126, 55, + 126, -1, 126, 56, 126, -1, 126, 34, 126, -1, + 126, 44, 126, -1, 126, 48, 126, -1, 126, 36, + 126, -1, 134, -1, 53, 127, -1, 56, 127, -1, + 49, 127, -1, 50, 127, -1, 69, 127, -1, 70, + 127, -1, 52, 127, -1, 36, 127, -1, 134, 59, + 60, -1, 134, 59, 187, 191, 60, -1, 134, 59, + 187, 11, 191, 60, -1, 3, -1, 143, -1, 134, + 63, 141, -1, 134, 63, 59, 135, 60, -1, 134, + 63, 59, 31, 60, -1, 134, 71, 126, 72, -1, + 134, 71, 192, 66, 192, 72, -1, 128, -1, 149, + 59, 126, 191, 60, -1, 150, 137, 130, 189, 68, + -1, 129, 67, 130, 189, 68, -1, 59, 135, 60, + 67, 130, 189, 68, -1, 165, -1, -1, 126, 66, + 133, -1, 126, -1, 67, 130, 189, 68, -1, 126, + -1, 67, 130, 189, 68, -1, 129, -1, 59, 135, + 60, -1, 126, -1, 147, -1, 146, -1, 35, -1, + 67, -1, 141, -1, 141, -1, -1, 138, -1, 24, + -1, 142, -1, 73, -1, 74, 3, 63, 24, -1, + 141, -1, 138, -1, 11, -1, 11, 146, -1, 155, + -1, 161, -1, 153, -1, 154, -1, 152, -1, 59, + 146, 60, -1, 155, -1, 161, -1, 153, -1, 53, + 147, -1, 161, -1, 153, -1, 154, -1, 152, -1, + 59, 146, 60, -1, 161, -1, 153, -1, 153, -1, + 155, -1, 161, -1, 153, -1, 154, -1, 152, -1, + 143, -1, 143, 63, 141, -1, 71, 192, 72, 146, + -1, 71, 11, 72, 146, -1, 8, 148, -1, 8, + 36, 146, -1, 23, 71, 146, 72, 146, -1, 156, + -1, 157, -1, 53, 146, -1, 36, 8, 146, -1, + 29, 137, 170, 190, 68, -1, 29, 137, 68, -1, + 22, 137, 171, 190, 68, -1, 22, 137, 68, -1, + 17, 159, 162, -1, 141, 59, 179, 60, 163, -1, + 59, 179, 60, 141, 59, 179, 60, 163, -1, 200, + 59, 195, 60, 210, -1, 59, 215, 60, 141, 59, + 195, 60, 210, -1, 17, 59, 179, 60, 163, -1, + -1, 67, 183, 68, -1, -1, 151, -1, 59, 179, + 60, -1, 161, -1, 164, 137, 183, 68, -1, 164, + 1, -1, -1, 166, 90, 62, -1, 93, -1, 167, + 62, 93, -1, 95, -1, 168, 62, 95, -1, 97, + -1, 169, 62, 97, -1, 172, -1, 170, 62, 172, + -1, 175, -1, 171, 62, 175, -1, 184, 146, 198, + -1, 174, 198, -1, 59, 174, 60, 198, -1, 53, + 174, 198, -1, 59, 53, 174, 60, 198, -1, 53, + 59, 174, 60, 198, -1, 24, -1, 24, 63, 141, + -1, 173, -1, 138, 176, -1, 173, -1, 59, 173, + 60, -1, 59, 179, 60, 163, -1, 136, -1, 141, + 136, -1, 141, 145, -1, 145, -1, 177, -1, 178, + 75, 177, -1, -1, 178, 191, -1, -1, 100, -1, + 91, -1, 181, -1, 1, -1, 98, -1, 110, -1, + 121, -1, 124, -1, 113, -1, -1, 144, 66, 182, + 180, -1, 15, -1, 6, 140, -1, 10, 140, -1, + 18, 128, -1, 13, 128, -1, 19, 138, -1, 27, + 193, -1, 180, -1, 183, 62, 180, -1, 138, -1, + 184, 75, 138, -1, 139, -1, 185, 75, 139, -1, + 126, -1, 186, 75, 126, -1, 135, -1, 187, 75, + 135, -1, 131, -1, 132, -1, 188, 75, 131, -1, + 188, 75, 132, -1, -1, 188, 191, -1, -1, 62, + -1, -1, 75, -1, -1, 126, -1, -1, 186, -1, + -1, 98, -1, -1, 215, -1, -1, 216, -1, -1, + 217, -1, -1, 3, -1, 21, 24, 3, 62, -1, + 32, 200, 202, 62, -1, 9, 200, 65, 213, 62, + -1, 9, 200, 202, 65, 213, 62, -1, 31, 201, + 202, 62, -1, 17, 160, 162, 62, -1, 142, -1, + 200, -1, 204, -1, 205, -1, 206, -1, 204, -1, + 206, -1, 142, -1, 24, -1, 71, 72, 202, -1, + 71, 3, 72, 202, -1, 23, 71, 202, 72, 202, + -1, 29, 67, 196, 68, -1, 22, 67, 197, 68, + -1, 53, 202, -1, 8, 203, -1, 8, 59, 205, + 60, -1, 8, 36, 202, -1, 36, 8, 202, -1, + 17, 59, 195, 60, 210, -1, 141, 202, 198, -1, + 141, 11, 202, 198, -1, 141, 202, 198, -1, 141, + 59, 195, 60, 210, -1, 202, -1, -1, 211, -1, + 59, 195, 60, -1, 202, -1, 3, -1, 50, 3, + -1, 141, -1, 212, -1, 59, 212, 49, 212, 60, + -1, -1, 214, 199, -1, 207, -1, 215, 75, 207, + -1, 208, -1, 216, 62, 208, -1, 209, -1, 217, + 62, 209, -1 }; /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ @@ -676,36 +661,36 @@ static const yytype_uint16 yyrline[] = 259, 260, 267, 267, 280, 284, 285, 289, 294, 300, 304, 308, 312, 318, 324, 330, 335, 339, 343, 349, 355, 359, 363, 369, 373, 379, 380, 384, 390, 399, - 405, 409, 414, 426, 442, 447, 454, 474, 492, 501, - 520, 519, 531, 530, 561, 564, 571, 570, 581, 587, - 596, 607, 613, 616, 624, 623, 634, 640, 652, 656, - 661, 651, 673, 676, 680, 687, 691, 686, 709, 708, - 724, 725, 729, 733, 737, 741, 745, 749, 753, 757, - 761, 765, 769, 773, 777, 781, 785, 789, 793, 797, - 802, 808, 809, 813, 824, 828, 832, 836, 841, 845, - 855, 859, 864, 872, 876, 877, 888, 892, 896, 900, - 904, 905, 911, 918, 924, 931, 934, 941, 947, 948, - 955, 956, 974, 975, 978, 981, 985, 996, 1005, 1011, - 1014, 1017, 1024, 1025, 1031, 1040, 1048, 1060, 1065, 1071, - 1072, 1073, 1074, 1075, 1076, 1082, 1083, 1084, 1085, 1091, - 1092, 1093, 1094, 1095, 1101, 1102, 1105, 1108, 1109, 1110, - 1111, 1112, 1115, 1116, 1129, 1133, 1138, 1143, 1148, 1152, - 1153, 1156, 1162, 1169, 1175, 1182, 1188, 1199, 1210, 1239, - 1278, 1301, 1318, 1327, 1330, 1338, 1342, 1346, 1353, 1359, - 1364, 1376, 1379, 1387, 1388, 1394, 1395, 1401, 1405, 1411, - 1412, 1418, 1422, 1428, 1451, 1456, 1462, 1468, 1475, 1484, - 1493, 1508, 1514, 1519, 1523, 1530, 1543, 1544, 1550, 1556, - 1559, 1563, 1569, 1572, 1581, 1584, 1585, 1589, 1590, 1596, - 1597, 1598, 1599, 1600, 1602, 1601, 1616, 1621, 1625, 1629, - 1633, 1637, 1642, 1661, 1667, 1675, 1679, 1685, 1689, 1695, - 1699, 1705, 1709, 1718, 1722, 1726, 1730, 1736, 1739, 1747, - 1748, 1750, 1751, 1754, 1757, 1760, 1763, 1766, 1769, 1772, - 1775, 1778, 1781, 1784, 1787, 1790, 1793, 1799, 1803, 1807, - 1811, 1815, 1819, 1837, 1844, 1855, 1856, 1857, 1860, 1861, - 1864, 1868, 1878, 1882, 1886, 1890, 1894, 1898, 1902, 1908, - 1914, 1922, 1930, 1936, 1943, 1959, 1977, 1981, 1987, 1990, - 1993, 1997, 2007, 2011, 2026, 2034, 2035, 2045, 2046, 2049, - 2053, 2059, 2063, 2069, 2073 + 405, 423, 428, 440, 456, 461, 468, 488, 506, 515, + 534, 533, 545, 544, 575, 578, 585, 584, 595, 601, + 610, 621, 627, 630, 638, 637, 648, 654, 666, 670, + 675, 665, 696, 695, 708, 711, 717, 720, 732, 736, + 731, 754, 753, 769, 770, 774, 778, 782, 786, 790, + 794, 798, 802, 806, 810, 814, 818, 822, 826, 830, + 834, 838, 842, 847, 853, 854, 858, 869, 873, 877, + 881, 886, 890, 900, 904, 909, 917, 921, 922, 933, + 937, 941, 945, 949, 950, 956, 963, 969, 976, 979, + 986, 992, 1009, 1016, 1017, 1024, 1025, 1044, 1045, 1048, + 1051, 1055, 1066, 1075, 1081, 1084, 1087, 1094, 1095, 1101, + 1116, 1124, 1136, 1141, 1147, 1148, 1149, 1150, 1151, 1152, + 1158, 1159, 1160, 1161, 1167, 1168, 1169, 1170, 1171, 1177, + 1178, 1181, 1184, 1185, 1186, 1187, 1188, 1191, 1192, 1205, + 1209, 1214, 1219, 1224, 1228, 1229, 1232, 1238, 1245, 1251, + 1258, 1264, 1275, 1289, 1318, 1358, 1383, 1401, 1410, 1413, + 1421, 1425, 1429, 1436, 1442, 1447, 1459, 1462, 1472, 1473, + 1479, 1480, 1486, 1490, 1496, 1497, 1503, 1507, 1513, 1536, + 1541, 1547, 1553, 1560, 1569, 1578, 1593, 1599, 1604, 1608, + 1615, 1628, 1629, 1635, 1641, 1644, 1648, 1654, 1657, 1666, + 1669, 1670, 1674, 1675, 1681, 1682, 1683, 1684, 1685, 1687, + 1686, 1701, 1706, 1710, 1714, 1718, 1722, 1727, 1746, 1752, + 1760, 1764, 1770, 1774, 1780, 1784, 1790, 1794, 1803, 1807, + 1811, 1815, 1821, 1824, 1832, 1833, 1835, 1836, 1839, 1842, + 1845, 1848, 1851, 1854, 1857, 1860, 1863, 1866, 1869, 1872, + 1875, 1878, 1884, 1888, 1892, 1896, 1900, 1904, 1924, 1931, + 1942, 1943, 1944, 1947, 1948, 1951, 1955, 1965, 1969, 1973, + 1977, 1981, 1985, 1989, 1995, 2001, 2009, 2017, 2023, 2030, + 2046, 2064, 2068, 2074, 2077, 2080, 2084, 2094, 2098, 2113, + 2121, 2122, 2134, 2135, 2138, 2142, 2148, 2152, 2158, 2162 }; #endif @@ -714,8 +699,8 @@ static const yytype_uint16 yyrline[] = First, the terminals, then, starting at YYNTOKENS, nonterminals. */ const char *yytname[] = { - "$end", "error", "$undefined", "LLITERAL", "LASOP", "LBREAK", "LCASE", - "LCHAN", "LCOLAS", "LCONST", "LCONTINUE", "LDDD", "LDEFAULT", "LDEFER", + "$end", "error", "$undefined", "LLITERAL", "LASOP", "LCOLAS", "LBREAK", + "LCASE", "LCHAN", "LCONST", "LCONTINUE", "LDDD", "LDEFAULT", "LDEFER", "LELSE", "LFALL", "LFOR", "LFUNC", "LGO", "LGOTO", "LIF", "LIMPORT", "LINTERFACE", "LMAP", "LNAME", "LPACKAGE", "LRANGE", "LRETURN", "LSELECT", "LSTRUCT", "LSWITCH", "LTYPE", "LVAR", "LANDAND", "LANDNOT", @@ -724,30 +709,31 @@ const char *yytname[] = "'/'", "'%'", "'&'", "NotPackage", "NotParen", "'('", "')'", "PreferToRightParen", "';'", "'.'", "'$'", "'='", "':'", "'{'", "'}'", "'!'", "'~'", "'['", "']'", "'?'", "'@'", "','", "$accept", "file", - "package", "loadsys", "$@1", "imports", "import", "import_stmt", + "package", "loadsys", "@1", "imports", "import", "import_stmt", "import_stmt_list", "import_here", "import_package", "import_safety", - "import_there", "$@2", "xdcl", "common_dcl", "lconst", "vardcl", + "import_there", "@2", "xdcl", "common_dcl", "lconst", "vardcl", "constdcl", "constdcl1", "typedclname", "typedcl", "simple_stmt", "case", - "compound_stmt", "$@3", "caseblock", "$@4", "caseblock_list", - "loop_body", "$@5", "range_stmt", "for_header", "for_body", "for_stmt", - "$@6", "if_header", "if_stmt", "$@7", "$@8", "$@9", "else", - "switch_stmt", "$@10", "$@11", "select_stmt", "$@12", "expr", "uexpr", - "pseudocall", "pexpr_no_paren", "start_complit", "keyval", "complitexpr", - "pexpr", "expr_or_type", "name_or_type", "lbrace", "new_name", - "dcl_name", "onew_name", "sym", "hidden_importsym", "name", "labelname", - "dotdotdot", "ntype", "non_expr_type", "non_recvchantype", "convtype", - "comptype", "fnret_type", "dotname", "othertype", "ptrtype", - "recvchantype", "structtype", "interfacetype", "xfndcl", "fndcl", - "hidden_fndcl", "fntype", "fnbody", "fnres", "fnlitdcl", "fnliteral", - "xdcl_list", "vardcl_list", "constdcl_list", "typedcl_list", - "structdcl_list", "interfacedcl_list", "structdcl", "packname", "embed", - "interfacedcl", "indcl", "arg_type", "arg_type_list", - "oarg_type_list_ocomma", "stmt", "non_dcl_stmt", "$@13", "stmt_list", - "new_name_list", "dcl_name_list", "expr_list", "expr_or_type_list", - "keyval_list", "braced_keyval_list", "osemi", "ocomma", "oexpr", - "oexpr_list", "osimple_stmt", "ohidden_funarg_list", - "ohidden_structdcl_list", "ohidden_interfacedcl_list", "oliteral", - "hidden_import", "hidden_pkg_importsym", "hidden_pkgtype", "hidden_type", + "compound_stmt", "@3", "caseblock", "@4", "caseblock_list", "loop_body", + "@5", "range_stmt", "for_header", "for_body", "for_stmt", "@6", + "if_header", "if_stmt", "@7", "@8", "@9", "elseif", "@10", "elseif_list", + "else", "switch_stmt", "@11", "@12", "select_stmt", "@13", "expr", + "uexpr", "pseudocall", "pexpr_no_paren", "start_complit", "keyval", + "bare_complitexpr", "complitexpr", "pexpr", "expr_or_type", + "name_or_type", "lbrace", "new_name", "dcl_name", "onew_name", "sym", + "hidden_importsym", "name", "labelname", "dotdotdot", "ntype", + "non_expr_type", "non_recvchantype", "convtype", "comptype", + "fnret_type", "dotname", "othertype", "ptrtype", "recvchantype", + "structtype", "interfacetype", "xfndcl", "fndcl", "hidden_fndcl", + "fntype", "fnbody", "fnres", "fnlitdcl", "fnliteral", "xdcl_list", + "vardcl_list", "constdcl_list", "typedcl_list", "structdcl_list", + "interfacedcl_list", "structdcl", "packname", "embed", "interfacedcl", + "indcl", "arg_type", "arg_type_list", "oarg_type_list_ocomma", "stmt", + "non_dcl_stmt", "@14", "stmt_list", "new_name_list", "dcl_name_list", + "expr_list", "expr_or_type_list", "keyval_list", "braced_keyval_list", + "osemi", "ocomma", "oexpr", "oexpr_list", "osimple_stmt", + "ohidden_funarg_list", "ohidden_structdcl_list", + "ohidden_interfacedcl_list", "oliteral", "hidden_import", + "hidden_pkg_importsym", "hidden_pkgtype", "hidden_type", "hidden_type_non_recv_chan", "hidden_type_misc", "hidden_type_recv_chan", "hidden_type_func", "hidden_funarg", "hidden_structdcl", "hidden_interfacedcl", "ohidden_funres", "hidden_funres", @@ -784,33 +770,33 @@ static const yytype_uint8 yyr1[] = 98, 98, 98, 98, 98, 98, 99, 99, 99, 99, 101, 100, 103, 102, 104, 104, 106, 105, 107, 107, 108, 108, 108, 109, 111, 110, 112, 112, 114, 115, - 116, 113, 117, 117, 117, 119, 120, 118, 122, 121, - 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, - 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, - 123, 124, 124, 124, 124, 124, 124, 124, 124, 124, - 125, 125, 125, 126, 126, 126, 126, 126, 126, 126, - 126, 126, 126, 126, 126, 126, 127, 128, 129, 129, - 130, 130, 131, 131, 132, 133, 133, 134, 135, 136, - 136, 137, 137, 137, 138, 139, 140, 141, 141, 142, - 142, 142, 142, 142, 142, 143, 143, 143, 143, 144, - 144, 144, 144, 144, 145, 145, 146, 147, 147, 147, - 147, 147, 148, 148, 149, 149, 149, 149, 149, 149, - 149, 150, 151, 152, 152, 153, 153, 154, 155, 155, - 156, 156, 157, 158, 158, 159, 159, 159, 160, 161, - 161, 162, 162, 163, 163, 164, 164, 165, 165, 166, - 166, 167, 167, 168, 168, 168, 168, 168, 168, 169, - 169, 170, 171, 171, 171, 172, 173, 173, 173, 173, - 174, 174, 175, 175, 176, 176, 176, 176, 176, 177, - 177, 177, 177, 177, 178, 177, 177, 177, 177, 177, - 177, 177, 177, 179, 179, 180, 180, 181, 181, 182, - 182, 183, 183, 184, 184, 184, 184, 185, 185, 186, - 186, 187, 187, 188, 188, 189, 189, 190, 190, 191, - 191, 192, 192, 193, 193, 194, 194, 195, 195, 195, - 195, 195, 195, 196, 197, 198, 198, 198, 199, 199, - 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, - 200, 201, 202, 203, 203, 204, 205, 205, 206, 206, - 207, 207, 208, 208, 208, 209, 209, 210, 210, 211, - 211, 212, 212, 213, 213 + 116, 113, 118, 117, 119, 119, 120, 120, 122, 123, + 121, 125, 124, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 127, 127, 127, 127, 127, 127, + 127, 127, 127, 128, 128, 128, 129, 129, 129, 129, + 129, 129, 129, 129, 129, 129, 129, 129, 129, 130, + 131, 132, 132, 133, 133, 134, 134, 135, 135, 136, + 137, 137, 138, 139, 140, 140, 141, 141, 141, 142, + 143, 144, 145, 145, 146, 146, 146, 146, 146, 146, + 147, 147, 147, 147, 148, 148, 148, 148, 148, 149, + 149, 150, 151, 151, 151, 151, 151, 152, 152, 153, + 153, 153, 153, 153, 153, 153, 154, 155, 156, 156, + 157, 157, 158, 159, 159, 160, 160, 161, 162, 162, + 163, 163, 163, 164, 165, 165, 166, 166, 167, 167, + 168, 168, 169, 169, 170, 170, 171, 171, 172, 172, + 172, 172, 172, 172, 173, 173, 174, 175, 175, 175, + 176, 177, 177, 177, 177, 178, 178, 179, 179, 180, + 180, 180, 180, 180, 181, 181, 181, 181, 181, 182, + 181, 181, 181, 181, 181, 181, 181, 181, 183, 183, + 184, 184, 185, 185, 186, 186, 187, 187, 188, 188, + 188, 188, 189, 189, 190, 190, 191, 191, 192, 192, + 193, 193, 194, 194, 195, 195, 196, 196, 197, 197, + 198, 198, 199, 199, 199, 199, 199, 199, 200, 201, + 202, 202, 202, 203, 203, 204, 204, 204, 204, 204, + 204, 204, 204, 204, 204, 204, 205, 206, 207, 207, + 208, 209, 209, 210, 210, 211, 211, 212, 212, 212, + 213, 213, 214, 214, 215, 215, 216, 216, 217, 217 }; /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ @@ -824,663 +810,674 @@ static const yytype_uint8 yyr2[] = 1, 3, 3, 3, 2, 2, 3, 5, 5, 2, 0, 4, 0, 3, 0, 2, 0, 4, 4, 4, 5, 1, 1, 2, 0, 3, 1, 3, 0, 0, - 0, 7, 0, 2, 2, 0, 0, 7, 0, 5, - 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 0, 8, 0, 5, 0, 2, 0, 2, 0, 0, + 7, 0, 5, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 1, 2, 2, 2, 2, 2, 2, 2, 2, - 3, 5, 6, 1, 1, 3, 5, 5, 4, 6, - 1, 4, 5, 5, 7, 1, 0, 3, 1, 4, - 1, 3, 1, 1, 1, 1, 1, 1, 1, 0, - 1, 1, 1, 1, 4, 1, 1, 1, 2, 1, - 1, 1, 1, 1, 3, 1, 1, 1, 2, 1, - 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 3, 4, 4, 2, 3, 5, 1, - 1, 2, 3, 5, 3, 5, 3, 3, 5, 8, - 5, 8, 5, 0, 3, 0, 1, 3, 1, 4, - 2, 0, 3, 1, 3, 1, 3, 1, 3, 1, - 3, 1, 3, 3, 2, 4, 3, 5, 5, 1, - 3, 1, 2, 1, 3, 4, 1, 2, 2, 1, - 1, 3, 0, 2, 0, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 0, 4, 1, 2, 2, 2, - 2, 2, 2, 1, 3, 1, 3, 1, 3, 1, - 3, 1, 3, 1, 1, 3, 3, 0, 2, 0, - 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, - 1, 0, 1, 0, 1, 0, 1, 4, 4, 5, - 6, 4, 4, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 3, 4, 5, 4, 4, 2, 2, 4, - 3, 3, 5, 3, 4, 3, 5, 1, 0, 1, - 3, 1, 1, 2, 1, 1, 5, 0, 2, 1, - 3, 1, 3, 1, 3 + 3, 3, 3, 3, 1, 2, 2, 2, 2, 2, + 2, 2, 2, 3, 5, 6, 1, 1, 3, 5, + 5, 4, 6, 1, 5, 5, 5, 7, 1, 0, + 3, 1, 4, 1, 4, 1, 3, 1, 1, 1, + 1, 1, 1, 1, 0, 1, 1, 1, 1, 4, + 1, 1, 1, 2, 1, 1, 1, 1, 1, 3, + 1, 1, 1, 2, 1, 1, 1, 1, 3, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 3, 4, + 4, 2, 3, 5, 1, 1, 2, 3, 5, 3, + 5, 3, 3, 5, 8, 5, 8, 5, 0, 3, + 0, 1, 3, 1, 4, 2, 0, 3, 1, 3, + 1, 3, 1, 3, 1, 3, 1, 3, 3, 2, + 4, 3, 5, 5, 1, 3, 1, 2, 1, 3, + 4, 1, 2, 2, 1, 1, 3, 0, 2, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, + 4, 1, 2, 2, 2, 2, 2, 2, 1, 3, + 1, 3, 1, 3, 1, 3, 1, 3, 1, 1, + 3, 3, 0, 2, 0, 1, 0, 1, 0, 1, + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, + 0, 1, 4, 4, 5, 6, 4, 4, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 3, 4, 5, + 4, 4, 2, 2, 4, 3, 3, 5, 3, 4, + 3, 5, 1, 0, 1, 3, 1, 1, 2, 1, + 1, 5, 0, 2, 1, 3, 1, 3, 1, 3 }; -/* YYDEFACT[STATE-NAME] -- Default reduction number in state STATE-NUM. - Performed when YYTABLE doesn't specify something else to do. Zero +/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state + STATE-NUM when YYTABLE doesn't specify something else to do. Zero means the default is an error. */ static const yytype_uint16 yydefact[] = { - 5, 0, 3, 0, 1, 0, 7, 0, 22, 151, - 153, 0, 0, 152, 211, 20, 6, 337, 0, 4, + 5, 0, 3, 0, 1, 0, 7, 0, 22, 156, + 158, 0, 0, 157, 216, 20, 6, 342, 0, 4, 0, 0, 0, 21, 0, 0, 0, 16, 0, 0, - 9, 22, 0, 8, 28, 123, 149, 0, 39, 149, - 0, 256, 74, 0, 0, 0, 78, 0, 0, 285, - 88, 0, 85, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 283, 0, 25, 0, 249, 250, - 253, 251, 252, 50, 90, 130, 140, 111, 156, 155, - 124, 0, 0, 0, 176, 189, 190, 26, 208, 0, - 135, 27, 0, 19, 0, 0, 0, 0, 0, 0, - 338, 154, 11, 14, 279, 18, 22, 13, 17, 150, - 257, 147, 0, 0, 0, 0, 155, 182, 186, 172, - 170, 171, 169, 258, 130, 0, 287, 242, 0, 203, - 130, 261, 287, 145, 146, 0, 0, 269, 286, 262, - 0, 0, 287, 0, 0, 36, 48, 0, 29, 267, - 148, 0, 119, 114, 115, 118, 112, 113, 0, 0, - 142, 0, 143, 167, 165, 166, 116, 117, 0, 284, - 0, 212, 0, 32, 0, 0, 0, 0, 0, 55, + 9, 22, 0, 8, 28, 126, 154, 0, 39, 154, + 0, 261, 74, 0, 0, 0, 78, 0, 0, 290, + 91, 0, 88, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 288, 0, 25, 0, 254, 255, + 258, 256, 257, 50, 93, 133, 145, 114, 161, 160, + 127, 0, 0, 0, 181, 194, 195, 26, 213, 0, + 138, 27, 0, 19, 0, 0, 0, 0, 0, 0, + 343, 159, 11, 14, 284, 18, 22, 13, 17, 155, + 262, 152, 0, 0, 0, 0, 160, 187, 191, 177, + 175, 176, 174, 263, 133, 0, 292, 247, 0, 208, + 133, 266, 292, 150, 151, 0, 0, 274, 291, 267, + 0, 0, 292, 0, 0, 36, 48, 0, 29, 272, + 153, 0, 122, 117, 118, 121, 115, 116, 0, 0, + 147, 0, 148, 172, 170, 171, 119, 120, 0, 289, + 0, 217, 0, 32, 0, 0, 0, 0, 0, 55, 0, 0, 0, 54, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 136, 0, - 0, 283, 254, 0, 136, 210, 0, 0, 0, 0, - 303, 0, 0, 203, 0, 0, 304, 0, 0, 23, - 280, 0, 12, 242, 0, 0, 187, 163, 161, 162, - 159, 160, 191, 0, 0, 288, 72, 0, 75, 0, - 71, 157, 236, 155, 239, 144, 240, 281, 0, 242, - 0, 197, 79, 76, 151, 0, 196, 0, 279, 233, - 221, 0, 64, 0, 0, 194, 265, 279, 219, 231, - 295, 0, 86, 38, 217, 279, 49, 31, 213, 279, - 0, 0, 40, 0, 168, 141, 0, 0, 35, 279, - 0, 0, 51, 92, 107, 110, 93, 97, 98, 96, - 108, 95, 94, 91, 109, 99, 100, 101, 102, 103, - 104, 105, 106, 277, 120, 271, 281, 0, 125, 284, - 0, 0, 0, 277, 248, 60, 246, 245, 263, 247, - 0, 53, 52, 270, 0, 0, 0, 0, 311, 0, - 0, 0, 0, 0, 310, 0, 305, 306, 307, 0, - 339, 0, 0, 289, 0, 0, 0, 15, 10, 0, - 0, 0, 173, 183, 66, 73, 0, 0, 287, 158, - 237, 238, 282, 243, 205, 0, 0, 0, 287, 0, - 229, 0, 242, 232, 280, 0, 0, 0, 0, 295, - 0, 0, 280, 0, 296, 224, 0, 295, 0, 280, - 0, 280, 0, 42, 268, 0, 0, 0, 192, 163, - 161, 162, 160, 136, 185, 184, 280, 0, 44, 0, - 136, 138, 273, 274, 281, 0, 281, 282, 0, 0, - 0, 128, 283, 255, 131, 0, 0, 0, 209, 0, - 0, 318, 308, 309, 289, 293, 0, 291, 0, 317, - 332, 0, 0, 334, 335, 0, 0, 0, 0, 0, - 295, 0, 0, 302, 0, 290, 297, 301, 298, 205, - 164, 0, 0, 0, 0, 241, 242, 155, 206, 181, - 179, 180, 177, 178, 202, 205, 204, 80, 77, 230, - 234, 0, 222, 195, 188, 0, 0, 89, 62, 65, - 0, 226, 0, 295, 220, 193, 266, 223, 64, 218, - 37, 214, 30, 41, 0, 277, 45, 215, 279, 47, - 33, 43, 277, 0, 282, 278, 133, 282, 0, 272, - 121, 127, 126, 0, 132, 0, 264, 320, 0, 0, - 311, 0, 310, 0, 327, 343, 294, 0, 0, 0, - 341, 292, 321, 333, 0, 299, 0, 312, 0, 295, - 323, 0, 340, 328, 0, 69, 68, 287, 0, 242, - 198, 82, 205, 0, 59, 0, 295, 295, 225, 0, - 164, 0, 280, 0, 46, 0, 138, 137, 275, 276, - 122, 129, 61, 319, 328, 289, 316, 0, 0, 295, - 315, 0, 0, 313, 300, 324, 289, 289, 331, 200, - 329, 67, 70, 207, 0, 0, 81, 235, 0, 0, - 56, 0, 63, 228, 227, 87, 134, 216, 34, 139, - 322, 0, 344, 314, 325, 342, 0, 0, 0, 205, - 84, 83, 0, 0, 328, 336, 328, 330, 199, 58, - 57, 326, 201 + 0, 0, 0, 0, 0, 0, 0, 0, 139, 0, + 0, 288, 259, 0, 139, 215, 0, 0, 0, 0, + 308, 0, 0, 208, 0, 0, 309, 0, 0, 23, + 285, 0, 12, 247, 0, 0, 192, 168, 166, 167, + 164, 165, 196, 0, 0, 293, 72, 0, 75, 0, + 71, 162, 241, 160, 244, 149, 245, 286, 0, 247, + 0, 202, 79, 76, 156, 0, 201, 0, 284, 238, + 226, 0, 64, 0, 0, 199, 270, 284, 224, 236, + 300, 0, 89, 38, 222, 284, 49, 31, 218, 284, + 0, 0, 40, 0, 173, 146, 0, 0, 35, 284, + 0, 0, 51, 95, 110, 113, 96, 100, 101, 99, + 111, 98, 97, 94, 112, 102, 103, 104, 105, 106, + 107, 108, 109, 282, 123, 276, 286, 0, 128, 289, + 0, 0, 286, 282, 253, 60, 251, 250, 268, 252, + 0, 53, 52, 275, 0, 0, 0, 0, 316, 0, + 0, 0, 0, 0, 315, 0, 310, 311, 312, 0, + 344, 0, 0, 294, 0, 0, 0, 15, 10, 0, + 0, 0, 178, 188, 66, 73, 0, 0, 292, 163, + 242, 243, 287, 248, 210, 0, 0, 0, 292, 0, + 234, 0, 247, 237, 285, 0, 0, 0, 0, 300, + 0, 0, 285, 0, 301, 229, 0, 300, 0, 285, + 0, 285, 0, 42, 273, 0, 0, 0, 197, 168, + 166, 167, 165, 139, 190, 189, 285, 0, 44, 0, + 139, 141, 278, 279, 286, 0, 286, 287, 0, 0, + 0, 131, 288, 260, 287, 0, 0, 0, 0, 214, + 0, 0, 323, 313, 314, 294, 298, 0, 296, 0, + 322, 337, 0, 0, 339, 340, 0, 0, 0, 0, + 0, 300, 0, 0, 307, 0, 295, 302, 306, 303, + 210, 169, 0, 0, 0, 0, 246, 247, 160, 211, + 186, 184, 185, 182, 183, 207, 210, 209, 80, 77, + 235, 239, 0, 227, 200, 193, 0, 0, 92, 62, + 65, 0, 231, 0, 300, 225, 198, 271, 228, 64, + 223, 37, 219, 30, 41, 0, 282, 45, 220, 284, + 47, 33, 43, 282, 0, 287, 283, 136, 0, 277, + 124, 130, 129, 0, 134, 135, 0, 269, 325, 0, + 0, 316, 0, 315, 0, 332, 348, 299, 0, 0, + 0, 346, 297, 326, 338, 0, 304, 0, 317, 0, + 300, 328, 0, 345, 333, 0, 69, 68, 292, 0, + 247, 203, 84, 210, 0, 59, 0, 300, 300, 230, + 0, 169, 0, 285, 0, 46, 0, 139, 143, 140, + 280, 281, 125, 132, 61, 324, 333, 294, 321, 0, + 0, 300, 320, 0, 0, 318, 305, 329, 294, 294, + 336, 205, 334, 67, 70, 212, 0, 86, 240, 0, + 0, 56, 0, 63, 233, 232, 90, 137, 221, 34, + 142, 282, 327, 0, 349, 319, 330, 347, 0, 0, + 0, 210, 0, 85, 81, 0, 0, 0, 333, 341, + 333, 335, 204, 82, 87, 58, 57, 144, 331, 206, + 292, 0, 83 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int16 yydefgoto[] = { -1, 1, 6, 2, 3, 14, 21, 30, 104, 31, - 8, 24, 16, 17, 65, 326, 67, 148, 516, 517, - 144, 145, 68, 498, 327, 436, 499, 575, 387, 365, - 471, 236, 237, 238, 69, 126, 252, 70, 132, 377, - 571, 616, 71, 142, 398, 72, 140, 73, 74, 75, - 76, 313, 422, 423, 77, 315, 242, 135, 78, 149, - 110, 116, 13, 80, 81, 244, 245, 162, 118, 82, - 83, 478, 227, 84, 229, 230, 85, 86, 87, 129, - 213, 88, 251, 484, 89, 90, 22, 279, 518, 275, - 267, 258, 268, 269, 270, 260, 383, 246, 247, 248, - 328, 329, 321, 330, 271, 151, 92, 316, 424, 425, - 221, 373, 170, 139, 253, 464, 549, 543, 395, 100, - 211, 217, 608, 441, 346, 347, 348, 350, 550, 545, - 609, 610, 454, 455, 25, 465, 551, 546 + 8, 24, 16, 17, 65, 326, 67, 148, 517, 518, + 144, 145, 68, 499, 327, 437, 500, 576, 387, 365, + 472, 236, 237, 238, 69, 126, 252, 70, 132, 377, + 572, 643, 660, 617, 644, 71, 142, 398, 72, 140, + 73, 74, 75, 76, 313, 422, 423, 589, 77, 315, + 242, 135, 78, 149, 110, 116, 13, 80, 81, 244, + 245, 162, 118, 82, 83, 479, 227, 84, 229, 230, + 85, 86, 87, 129, 213, 88, 251, 485, 89, 90, + 22, 279, 519, 275, 267, 258, 268, 269, 270, 260, + 383, 246, 247, 248, 328, 329, 321, 330, 271, 151, + 92, 316, 424, 425, 221, 373, 170, 139, 253, 465, + 550, 544, 395, 100, 211, 217, 610, 442, 346, 347, + 348, 350, 551, 546, 611, 612, 455, 456, 25, 466, + 552, 547 }; /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing STATE-NUM. */ -#define YYPACT_NINF -551 +#define YYPACT_NINF -485 static const yytype_int16 yypact[] = { - -551, 46, 48, 121, -551, 58, -551, 135, -551, -551, - -551, 65, 72, -551, 147, 156, -551, -551, 112, -551, - 50, 134, 904, -551, 162, 463, 209, -551, 54, 237, - -551, 121, 245, -551, -551, -551, 58, 1666, -551, 58, - 288, -551, -551, 34, 288, 58, -551, 36, 184, 1467, - -551, 36, -551, 316, 462, 1467, 1467, 1467, 1467, 1467, - 1467, 1522, 1467, 1467, 965, 198, -551, 506, -551, -551, - -551, -551, -551, 796, -551, -551, 195, 1, -551, 199, - -551, 207, 216, 36, 221, -551, -551, -551, 226, 53, - -551, -551, 108, -551, 214, 110, 269, 214, 214, 233, - -551, -551, -551, -551, 238, -551, -551, -551, -551, -551, - -551, -551, 242, 1691, 1691, 1691, -551, 240, -551, -551, - -551, -551, -551, -551, 154, 1, 1467, 1658, 247, 246, - 290, -551, 1467, -551, -551, 419, 1691, 2004, 229, -551, - 272, 333, 1467, 258, 1691, -551, -551, 485, -551, -551, - -551, 656, -551, -551, -551, -551, -551, -551, 1577, 1522, - 2004, 255, -551, 10, -551, 51, -551, -551, 251, 2004, - 256, -551, 508, -551, 1632, 1467, 1467, 1467, 1467, -551, - 1467, 1467, 1467, -551, 1467, 1467, 1467, 1467, 1467, 1467, - 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, -551, 1192, - 552, 1467, -551, 1467, -551, -551, 1134, 1467, 1467, 1467, - -551, 1203, 58, 246, 260, 332, -551, 1838, 1838, -551, - 76, 282, -551, 1658, 344, 1691, -551, -551, -551, -551, - -551, -551, -551, 293, 58, -551, -551, 328, -551, 178, - 303, 1691, -551, 1658, -551, -551, -551, 295, 308, 1658, - 1134, -551, -551, 309, 271, 364, -551, 334, 337, -551, - -551, 330, -551, 11, 66, -551, -551, 342, -551, -551, - 397, 664, -551, -551, -551, 351, -551, -551, -551, 352, - 1467, 58, 343, 1719, -551, 349, 1691, 1691, -551, 356, - 1467, 357, 2004, 2075, -551, 2028, 692, 692, 692, 692, - -551, 692, 692, 2052, -551, 593, 593, 593, 593, -551, - -551, -551, -551, 1247, -551, -551, 22, 1302, -551, 1877, - 355, 1060, 1979, 1247, -551, -551, -551, -551, -551, -551, - 86, 229, 229, 2004, 1777, 367, 361, 359, -551, 366, - 427, 1838, 52, 29, -551, 370, -551, -551, -551, 784, - -551, 118, 379, 58, 396, 400, 401, -551, -551, 404, - 1691, 409, -551, -551, -551, -551, 1357, 1412, 1467, -551, - -551, -551, 1658, -551, 1744, 414, 109, 328, 1467, 58, - 416, 423, 1658, -551, 561, 417, 1691, 44, 364, 397, - 364, 428, 451, 421, -551, -551, 58, 397, 456, 58, - 436, 58, 438, 229, -551, 1467, 1752, 1691, -551, 24, - 171, 287, 338, -551, -551, -551, 58, 439, 229, 1467, - -551, 1907, -551, -551, 425, 435, 430, 1522, 446, 448, - 453, -551, 1467, -551, -551, 443, 1134, 1060, -551, 1838, - 479, -551, -551, -551, 58, 1805, 1838, 58, 1838, -551, - -551, 514, 161, -551, -551, 460, 454, 1838, 52, 1838, - 397, 58, 58, -551, 458, 459, -551, -551, -551, 1744, - -551, 1134, 1467, 1467, 467, -551, 1658, 472, -551, -551, - -551, -551, -551, -551, -551, 1744, -551, -551, -551, -551, - -551, 477, -551, -551, -551, 1522, 474, -551, -551, -551, - 482, -551, 500, 397, -551, -551, -551, -551, -551, -551, - -551, -551, -551, 229, 501, 1247, -551, -551, 505, 1632, - -551, 229, 1247, 1247, 1247, -551, -551, -551, 503, -551, - -551, -551, -551, 511, -551, 137, -551, -551, 518, 528, - 532, 534, 535, 530, -551, -551, 537, 533, 1838, 536, - -551, 538, -551, -551, 560, -551, 1838, -551, 551, 397, - -551, 557, -551, 1830, 151, 2004, 2004, 1467, 558, 1658, - -551, 605, 1744, 125, -551, 1060, 397, 397, -551, 75, - 360, 554, 58, 563, 357, 556, 2004, -551, -551, -551, - -551, -551, -551, -551, 1830, 58, -551, 1805, 1838, 397, - -551, 58, 161, -551, -551, -551, 58, 58, -551, -551, - -551, -551, -551, -551, 570, 78, -551, -551, 1467, 1467, - -551, 1522, 569, -551, -551, -551, -551, -551, -551, -551, - -551, 576, -551, -551, -551, -551, 578, 582, 584, 1744, - -551, -551, 1931, 1955, 1830, -551, 1830, -551, -551, -551, - -551, -551, -551 + -485, 67, 35, 55, -485, 44, -485, 64, -485, -485, + -485, 96, 38, -485, 77, 85, -485, -485, 66, -485, + 34, 84, 1059, -485, 86, 294, 147, -485, 165, 210, + -485, 55, 221, -485, -485, -485, 44, 1762, -485, 44, + 290, -485, -485, 442, 290, 44, -485, 80, 69, 1608, + -485, 80, -485, 450, 452, 1608, 1608, 1608, 1608, 1608, + 1608, 1651, 1608, 1608, 920, 157, -485, 460, -485, -485, + -485, -485, -485, 718, -485, -485, 167, 344, -485, 176, + -485, 180, 193, 80, 206, -485, -485, -485, 218, 91, + -485, -485, 76, -485, 205, 10, 260, 205, 205, 223, + -485, -485, -485, -485, 230, -485, -485, -485, -485, -485, + -485, -485, 237, 1770, 1770, 1770, -485, 236, -485, -485, + -485, -485, -485, -485, 220, 344, 1608, 990, 241, 235, + 262, -485, 1608, -485, -485, 405, 1770, 2090, 254, -485, + 297, 444, 1608, 61, 1770, -485, -485, 271, -485, -485, + -485, 671, -485, -485, -485, -485, -485, -485, 1694, 1651, + 2090, 291, -485, 181, -485, 60, -485, -485, 287, 2090, + 301, -485, 496, -485, 912, 1608, 1608, 1608, 1608, -485, + 1608, 1608, 1608, -485, 1608, 1608, 1608, 1608, 1608, 1608, + 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, -485, 1290, + 468, 1608, -485, 1608, -485, -485, 1221, 1608, 1608, 1608, + -485, 573, 44, 235, 275, 347, -485, 1301, 1301, -485, + 113, 302, -485, 990, 358, 1770, -485, -485, -485, -485, + -485, -485, -485, 316, 44, -485, -485, 340, -485, 78, + 318, 1770, -485, 990, -485, -485, -485, 307, 325, 990, + 1221, -485, -485, 324, 117, 365, -485, 343, 337, -485, + -485, 333, -485, 32, 23, -485, -485, 350, -485, -485, + 406, 1737, -485, -485, -485, 351, -485, -485, -485, 352, + 1608, 44, 354, 1796, -485, 353, 1770, 1770, -485, 359, + 1608, 357, 2090, 1928, -485, 2114, 1212, 1212, 1212, 1212, + -485, 1212, 1212, 2138, -485, 566, 566, 566, 566, -485, + -485, -485, -485, 1345, -485, -485, 31, 1400, -485, 1988, + 360, 1147, 1955, 1345, -485, -485, -485, -485, -485, -485, + 95, 254, 254, 2090, 1857, 368, 361, 371, -485, 363, + 427, 1301, 247, 51, -485, 374, -485, -485, -485, 1890, + -485, 36, 382, 44, 384, 385, 387, -485, -485, 391, + 1770, 395, -485, -485, -485, -485, 1455, 1510, 1608, -485, + -485, -485, 990, -485, 1823, 399, 135, 340, 1608, 44, + 397, 403, 990, -485, 542, 407, 1770, 278, 365, 406, + 365, 411, 364, 413, -485, -485, 44, 406, 430, 44, + 423, 44, 425, 254, -485, 1608, 1849, 1770, -485, 216, + 219, 274, 288, -485, -485, -485, 44, 426, 254, 1608, + -485, 2018, -485, -485, 414, 422, 416, 1651, 433, 434, + 436, -485, 1608, -485, -485, 439, 437, 1221, 1147, -485, + 1301, 466, -485, -485, -485, 44, 1882, 1301, 44, 1301, + -485, -485, 504, 207, -485, -485, 446, 438, 1301, 247, + 1301, 406, 44, 44, -485, 453, 455, -485, -485, -485, + 1823, -485, 1221, 1608, 1608, 467, -485, 990, 472, -485, + -485, -485, -485, -485, -485, -485, 1823, -485, -485, -485, + -485, -485, 475, -485, -485, -485, 1651, 470, -485, -485, + -485, 490, -485, 493, 406, -485, -485, -485, -485, -485, + -485, -485, -485, -485, 254, 495, 1345, -485, -485, 498, + 912, -485, 254, 1345, 1553, 1345, -485, -485, 497, -485, + -485, -485, -485, 486, -485, -485, 143, -485, -485, 501, + 502, 473, 508, 513, 505, -485, -485, 515, 503, 1301, + 511, -485, 518, -485, -485, 533, -485, 1301, -485, 522, + 406, -485, 526, -485, 1916, 144, 2090, 2090, 1608, 527, + 990, -485, -485, 1823, 39, -485, 1147, 406, 406, -485, + 315, 293, 521, 44, 548, 357, 525, -485, 2090, -485, + -485, -485, -485, -485, -485, -485, 1916, 44, -485, 1882, + 1301, 406, -485, 44, 207, -485, -485, -485, 44, 44, + -485, -485, -485, -485, -485, -485, 551, 572, -485, 1608, + 1608, -485, 1651, 550, -485, -485, -485, -485, -485, -485, + -485, 1345, -485, 558, -485, -485, -485, -485, 563, 564, + 565, 1823, 46, -485, -485, 2042, 2066, 559, 1916, -485, + 1916, -485, -485, -485, -485, -485, -485, -485, -485, -485, + 1608, 340, -485 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int16 yypgoto[] = { - -551, -551, -551, -551, -551, -551, -551, -6, -551, -551, - 608, -551, -11, -551, -551, 623, -551, -134, -25, 68, - -551, -135, -121, -551, 39, -551, -551, -551, 145, 278, - -551, -551, -551, -551, -551, -551, 515, 41, -551, -551, - -551, -551, -551, -551, -551, -551, -551, 579, 493, 45, - -551, -192, 138, -246, 192, -47, 415, 200, -20, 380, - 626, -5, 449, 346, -551, 426, 95, 509, -551, -551, - -551, -551, -33, 38, -31, -18, -551, -551, -551, -551, - -551, 43, 457, -467, -551, -551, -551, -551, -551, -551, - -551, -551, 280, -126, -227, 292, -551, 302, -551, -220, - -297, 662, -551, -248, -551, -66, 18, 194, -551, -295, - -228, -289, -191, -551, -119, -403, -551, -551, -305, -551, - -32, -551, 127, -551, 362, 250, 363, 232, 90, 98, - -550, -551, -426, 241, -551, 486, -551, -551 + -485, -485, -485, -485, -485, -485, -485, -6, -485, -485, + 597, -485, -3, -485, -485, 608, -485, -131, -28, 50, + -485, -135, -106, -485, -7, -485, -485, -485, 125, -370, + -485, -485, -485, -485, -485, -485, -138, -485, -485, -485, + -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, + 665, 15, 116, -485, -190, 111, 112, -485, 164, -59, + 398, 137, 14, 367, 603, -5, 454, 432, -485, 402, + -50, 491, -485, -485, -485, -485, -36, 18, -34, -9, + -485, -485, -485, -485, -485, 257, 441, -445, -485, -485, + -485, -485, -485, -485, -485, -485, 259, -116, -218, 265, + -485, 284, -485, -217, -286, 636, -485, -237, -485, -62, + -24, 166, -485, -314, -246, -265, -177, -485, -115, -415, + -485, -485, -379, -485, -8, -485, 435, -485, 326, 225, + 327, 204, 65, 70, -484, -485, -426, 211, -485, 462, + -485, -485 }; /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If positive, shift that token. If negative, reduce the rule which - number is the opposite. If YYTABLE_NINF, syntax error. */ -#define YYTABLE_NINF -270 + number is the opposite. If zero, do what YYDEFACT says. + If YYTABLE_NINF, syntax error. */ +#define YYTABLE_NINF -275 static const yytype_int16 yytable[] = { - 12, 174, 376, 359, 119, 235, 121, 240, 274, 259, - 320, 235, 323, 278, 161, 32, 109, 79, 570, 109, - 107, 235, 103, 32, 433, 131, 554, 428, 435, 375, - 385, 111, 456, 426, 111, 380, 389, 391, 128, 393, - 111, 539, 173, 164, 630, -176, 4, 400, 146, 150, - 495, 402, -208, 27, 205, 450, 496, 27, 9, -172, - 199, 417, 150, 214, 200, 216, 218, 138, 18, -175, - 388, 133, 201, 5, 9, 120, 9, -176, 9, 27, - 122, 495, 9, -172, 501, 124, -208, 496, 133, 130, - 380, -172, 507, 127, 651, 222, 652, 427, 46, 163, - 9, 457, 451, 134, 165, 617, 174, 10, 11, 28, - -174, 452, 497, 29, 102, 257, 207, 29, -208, 390, - 134, 266, 243, 10, 11, 10, 11, 10, 11, 381, - 111, 10, 11, 618, 19, 525, 111, 528, 146, 29, - 536, 164, 150, 625, 239, 325, 7, 289, 437, 10, - 11, 228, 228, 228, 438, 560, 231, 231, 231, 15, - -260, 500, 491, 502, 450, 228, -260, 150, 20, 212, - 231, 437, 648, 208, 228, 26, 636, 486, 461, 231, - 23, 164, 228, 209, 11, 9, 366, 231, 535, 228, - 619, 620, 631, 462, 231, 318, 33, 163, 578, 437, - 621, 79, 165, 637, 638, 592, -170, 349, 226, 232, - 233, 451, 228, 437, 357, 32, -260, 231, 243, 611, - 581, 515, -260, 564, 93, 331, 332, 585, 522, 363, - -170, 261, 125, 101, 10, 11, 125, 163, -170, 276, - 105, 533, 165, 367, 243, 79, 282, 235, 108, 474, - 409, 141, 411, 209, 605, 136, 568, 235, 259, 488, - 171, 228, 198, 228, 509, -147, 231, 511, 231, 291, - 430, 623, 624, 202, -229, 203, 150, 587, 589, 228, - -175, 228, 9, 204, 231, -174, 231, 228, 11, 206, - 583, 35, 231, 215, 634, 37, -259, 219, 403, 164, - 220, 223, -259, 234, 209, 112, 249, 262, 418, 228, - 47, 48, 9, 250, 231, 285, 79, 51, 273, 353, - 361, 410, -171, 286, 228, 228, 412, 622, 287, 231, - 231, 10, 11, -229, 379, 354, 369, 453, 345, -229, - 9, 479, 358, 481, 355, 356, -171, 61, 349, 614, - 519, 360, -259, 362, -171, 163, 482, 254, -259, 64, - 165, 10, 11, 364, 257, 368, 397, 243, 374, 477, - 372, 378, 266, -169, 489, 143, 506, 243, 408, 111, - 529, 414, 415, 117, 331, 332, 263, 111, 380, 10, - 11, 111, 264, 382, 146, -173, 150, -169, 228, 384, - 394, 265, 386, 231, 392, -169, 10, 11, 405, 164, - 228, 150, 480, 399, 401, 231, 413, 483, 416, -173, - 228, 432, 419, 513, 228, 231, 444, -173, 445, 231, - 446, 79, 79, 447, 448, 458, 479, 521, 481, 349, - 541, 463, 548, 254, 228, 228, 235, 453, 612, 231, - 231, 482, 479, 453, 481, 408, 561, 349, 466, 117, - 117, 117, 467, 468, 469, 163, 79, 482, 449, 470, - 165, 243, 94, 117, 485, 254, 460, 164, 255, 379, - 95, 494, 117, 490, 96, 493, 9, 256, 503, 505, - 117, 508, 10, 11, 97, 98, 510, 117, 512, 520, - 524, 226, 514, 526, 263, 527, 530, 480, 531, 9, - 264, 534, 483, 532, 228, 340, 519, 553, 563, 231, - 117, 147, 555, 480, 10, 11, 556, 99, 483, 567, - 9, 569, 9, 163, 462, 10, 11, 572, 165, 479, - 574, 481, 576, 210, 210, 277, 210, 210, 152, 153, - 154, 155, 156, 157, 482, 166, 167, 228, 10, 11, - 577, 580, 231, 590, 243, 172, 537, 582, 288, 117, - 79, 117, 544, 547, 529, 552, 9, 150, 593, 10, - 11, 10, 11, 591, 557, 254, 559, 117, 594, 117, - 349, -151, 541, 595, -152, 117, 548, 453, 596, 597, - 601, 349, 349, 164, 600, 598, 479, 228, 481, 602, - 480, 317, 231, 604, 584, 483, 606, 117, 613, 615, - 255, 482, 626, 628, 629, 10, 11, 177, 137, 117, - 639, 437, 117, 117, 10, 11, 644, 185, 645, 106, - 160, 189, 646, 169, 647, 66, 194, 195, 196, 197, - 627, 152, 156, 579, 640, 487, 641, 272, 370, 163, - 344, 404, 588, 37, 165, 123, 344, 344, 284, 371, - 352, 37, 504, 112, 475, 599, 492, 480, 47, 48, - 9, 112, 483, 603, 91, 51, 47, 48, 9, 573, - 538, 635, 224, 51, 562, 632, 442, 443, 351, 558, - 224, 0, 0, 0, 0, 0, 117, 0, 0, 114, - 0, 0, 0, 0, 0, 225, 0, 114, 117, 0, - 117, 280, 0, 225, 544, 633, 177, 64, 117, 10, - 11, 281, 117, 0, 0, 64, 185, 10, 11, 396, + 12, 119, 161, 121, 272, 174, 359, 488, 274, 436, + 502, 240, 385, 376, 323, 32, 278, 79, 508, 259, + 235, 393, 103, 32, 320, 138, 235, 555, 107, 400, + 540, 111, 375, 402, 111, 433, 235, 27, 128, 173, + 111, 571, 426, 417, 619, 389, 391, 380, 146, 150, + 109, 428, 164, 109, 457, 120, 380, 435, 9, 131, + 5, -213, 150, 226, 232, 233, 653, 4, 9, 212, + 152, 153, 154, 155, 156, 157, 390, 166, 167, 163, + 7, 207, 561, 366, 11, 9, 261, 214, 15, 216, + 218, 388, 205, 28, 276, -213, 462, 29, 20, 18, + 19, 282, 239, 222, 620, 621, 427, 10, 11, 23, + 174, 463, 632, 325, 622, 133, 27, 10, 11, -179, + -234, 273, 243, 458, 291, 579, 133, -213, 618, 26, + 111, 228, 228, 228, 10, 11, 111, 9, 146, 381, + 136, 208, 150, 367, 289, 228, 33, 134, 93, 257, + 164, 209, 537, 209, 228, 266, 124, 438, 134, 526, + 130, 528, 228, 439, 658, 492, 659, 150, 27, 228, + 501, 101, 503, 152, 156, 361, 29, 163, 638, -234, + 379, 607, 633, 331, 332, -234, 10, 11, 141, 9, + 164, 369, 228, 639, 640, 318, 652, 438, 624, 625, + 536, 79, 582, 487, 125, 438, 438, 349, 125, 586, + 451, 594, 613, 105, 357, 32, -181, 163, 243, 171, + 204, 397, 636, 516, 108, 102, 206, -265, 29, 363, + 523, 9, -265, 408, 198, 565, 414, 415, 10, 11, + -180, 228, -152, 228, 243, 79, 202, 409, -181, 411, + 451, -177, 203, 475, -175, 533, 403, 452, 430, 228, + 569, 228, 235, 489, 510, -180, 418, 228, 259, -264, + 512, 9, 235, 584, -264, -177, 150, -179, -175, 11, + 10, 11, -265, -177, 215, 496, -175, 219, -265, 228, + 497, 662, 220, 35, 122, 9, 223, 452, 37, 234, + 249, 410, 250, 94, 228, 228, 453, 112, 164, -176, + 408, 95, 47, 48, 9, 96, 79, 647, 165, 51, + 10, 11, 496, -174, -264, 97, 98, 497, -178, 209, + -264, 277, 262, -176, 353, 163, 495, 454, 480, 623, + 482, -176, 331, 332, 10, 11, 498, -174, 349, 61, + 354, 285, -178, 616, 520, -174, 226, 515, 99, 286, + -178, 64, 358, 10, 11, 483, 360, 243, 529, 478, + 231, 231, 231, 287, 490, 364, 362, 243, 228, 111, + 368, 514, 372, 626, 231, 374, 378, 111, 254, 380, + 228, 111, 481, 231, 146, 522, 150, 631, 257, 384, + 228, 231, 382, 199, 228, 386, 266, 200, 231, 394, + 507, 150, 392, 399, 401, 201, 165, 263, 164, 405, + 413, 416, 419, 264, 228, 228, 432, 445, 446, 254, + 448, 231, 79, 79, 480, 449, 482, 10, 11, 459, + 349, 542, 447, 549, 464, 163, 467, 468, 454, 469, + 480, 470, 482, 614, 454, 471, 165, 562, 349, 486, + 379, 483, 235, 491, 255, 509, 9, 79, 254, 117, + 585, 504, 243, 256, 9, 494, 9, 483, 10, 11, + 231, 506, 231, 511, 9, 513, 521, 164, 481, 525, + 527, 434, 9, 530, 531, 228, 532, 263, 231, 534, + 231, 127, 340, 264, 481, 535, 231, 554, 556, 143, + 557, 147, 265, 564, 163, 10, 11, 10, 11, 172, + 9, 520, 661, 10, 11, 10, 11, 317, 231, 568, + 463, 570, -156, 10, 11, 573, 575, 480, 228, 482, + 412, 10, 11, 231, 231, 117, 117, 117, 210, 210, + 577, 210, 210, 578, 235, 581, 288, 592, 593, 117, + 583, 595, 596, 529, 483, 243, 254, 597, 117, 10, + 11, 79, -157, 598, 165, 600, 117, 599, 150, 602, + 603, 334, 604, 117, 606, 608, 642, 615, 228, 627, + 335, 481, 349, 630, 542, 336, 337, 338, 549, 454, + 177, 255, 339, 349, 349, 480, 117, 482, 629, 340, + 185, 641, 438, 164, 189, 10, 11, 231, 648, 194, + 195, 196, 197, 649, 650, 651, 341, 657, 106, 231, + 66, 484, 483, 628, 580, 654, 590, 591, 342, 231, + 163, 370, 123, 231, 343, 371, 345, 11, 404, 493, + 284, 505, 355, 356, 352, 117, 476, 117, 91, 481, + 443, 444, 574, 231, 231, 344, 539, 563, 637, 634, + 559, 344, 344, 117, 351, 117, 0, 0, 0, 37, + 0, 117, 0, 0, 165, 0, 0, 0, 112, 0, + 0, 0, 0, 47, 48, 9, 0, 0, 0, 0, + 51, 0, 0, 117, 0, 0, 0, 224, 0, 0, + 0, 0, 0, 0, 137, 117, 0, 0, 117, 117, + 0, 0, 175, -274, 114, 0, 160, 484, 0, 169, + 225, 0, 0, 0, 231, 0, 280, 0, 0, 0, + 0, 0, 64, 484, 10, 11, 281, 0, 0, 0, + 0, 176, 177, 165, 178, 179, 180, 181, 182, 0, + 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, + 193, 194, 195, 196, 197, 0, 450, 231, 0, 0, + 0, 0, 0, -274, 461, 0, 0, 0, 344, 0, + 0, 0, 117, -274, 0, 344, 0, 0, 0, 0, + 0, 0, 0, 344, 117, 0, 117, 0, 0, 0, + 0, 0, 0, 0, 117, 0, 0, 0, 117, 0, + 0, 0, 0, 0, 0, 0, 0, 231, 0, 0, + 484, 0, 0, 0, 0, 0, 0, 0, 117, 117, + 292, 293, 294, 295, 0, 296, 297, 298, 0, 299, + 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, + 310, 311, 312, 0, 160, 0, 319, 0, 322, 0, + 0, 0, 137, 137, 333, 538, 0, 0, 0, 165, + 0, 545, 548, 0, 553, 0, 0, 0, 0, 0, + 0, 0, 0, 558, 344, 560, 0, 0, 484, 0, + 543, 344, 117, 344, 0, 0, 0, 0, 0, 117, + 0, 0, 344, 0, 344, 0, 0, 0, 117, 0, + 37, 0, 0, 35, 0, 0, 0, 0, 37, 112, + 0, 168, 0, 0, 47, 48, 9, 112, 0, 0, + 0, 51, 47, 48, 9, 137, 0, 0, 224, 51, + 0, 0, 117, 0, 0, 137, 55, 0, 0, 0, + 0, 0, 0, 0, 0, 114, 0, 0, 0, 56, + 57, 225, 58, 59, 0, 0, 60, 290, 421, 61, + 0, 0, 160, 64, 601, 10, 11, 281, 421, 62, + 63, 64, 605, 10, 11, 0, 0, 0, 37, 0, + 0, 241, 117, 344, 0, 117, 0, 112, 0, 0, + 0, 344, 47, 48, 9, 0, 0, 0, 344, 51, + 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, + 0, 137, 137, 0, 545, 635, 0, 0, 0, 0, + 0, 0, 0, 114, 0, 0, 0, 0, 0, 225, + 344, 0, 0, 543, 344, 0, 0, 0, 0, -2, + 34, 64, 35, 10, 11, 36, 0, 37, 38, 39, + 137, 0, 40, 117, 41, 42, 43, 44, 45, 46, + 0, 47, 48, 9, 137, 0, 49, 50, 51, 52, + 53, 54, 160, 0, 0, 55, 0, 169, 0, 0, + 0, 0, 344, 0, 344, 0, 0, 0, 56, 57, + 0, 58, 59, 0, 0, 60, 0, 0, 61, 0, + 0, -24, 0, 0, 0, 0, 0, 0, 62, 63, + 64, 0, 10, 11, 0, 0, 0, 0, 566, 567, + 0, 0, 0, 0, 0, 0, 0, 0, 324, 0, + 35, 0, 0, 36, -249, 37, 38, 39, 0, -249, + 40, 160, 41, 42, 112, 44, 45, 46, 0, 47, + 48, 9, 0, 0, 49, 50, 51, 52, 53, 54, + 0, 421, 0, 55, 0, 0, 0, 0, 421, 588, + 421, 0, 0, 0, 0, 0, 56, 57, 0, 58, + 59, 0, 0, 60, 0, 0, 61, 0, 0, -249, + 0, 0, 0, 0, 325, -249, 62, 63, 64, 0, + 10, 11, 324, 0, 35, 0, 0, 36, 0, 37, + 38, 39, 0, 0, 40, 0, 41, 42, 112, 44, + 45, 46, 0, 47, 48, 9, 177, 0, 49, 50, + 51, 52, 53, 54, 0, 0, 185, 55, 0, 0, 189, 190, 191, 192, 193, 194, 195, 196, 197, 0, - 0, 0, 117, 117, 292, 293, 294, 295, 0, 296, - 297, 298, 0, 299, 300, 301, 302, 303, 304, 305, - 306, 307, 308, 309, 310, 311, 312, 0, 160, 0, - 319, 0, 322, 344, 0, 0, 137, 137, 333, 0, - 344, 334, 0, 0, 0, 459, 0, 0, 344, 0, - 175, 335, 0, 0, -269, 0, 336, 337, 338, 0, - 0, 0, 0, 339, 0, 117, 0, 0, 0, 0, - 340, 0, 117, 0, 0, 0, 0, 0, 0, 176, - 177, 117, 178, 179, 180, 181, 182, 341, 183, 184, - 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, - 195, 196, 197, 0, 0, 343, 0, 0, 11, 137, - 0, -269, 0, 0, 0, 117, 0, 0, 0, 137, - 0, -269, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 344, 0, - 0, 0, 421, 0, 542, 344, 160, 344, 0, 0, - 0, 0, 421, 0, -2, 34, 344, 35, 344, 36, - 0, 37, 0, 38, 39, 117, 0, 40, 117, 41, - 42, 43, 44, 45, 46, 0, 47, 48, 9, 0, - 0, 49, 50, 51, 52, 53, 54, 0, 0, 0, - 55, 0, 0, 0, 0, 137, 137, 0, 0, 0, - 0, 0, 0, 56, 57, 0, 58, 59, 0, 0, - 60, 0, 0, 61, 0, 0, -24, 0, 35, 0, - 0, 0, 37, 62, 63, 64, 168, 10, 11, 0, - 0, 0, 112, 0, 137, 117, 0, 47, 48, 9, - 0, 0, 0, 0, 51, 0, 0, 344, 137, 0, - 0, 55, 0, 0, 0, 344, 160, 0, 0, 0, - 0, 169, 344, 0, 56, 57, 0, 58, 59, 0, - 0, 60, 0, 0, 61, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 62, 63, 64, 0, 10, 11, - 0, 0, 0, 344, 0, 0, 542, 344, 0, 0, - 0, 565, 566, 0, 0, 0, 0, 0, 0, 0, - 0, 324, 0, 35, 0, 36, -244, 37, 0, 38, - 39, 0, -244, 40, 160, 41, 42, 112, 44, 45, - 46, 0, 47, 48, 9, 0, 0, 49, 50, 51, - 52, 53, 54, 344, 421, 344, 55, 0, 0, 0, - 0, 421, 586, 421, 0, 0, 0, 0, 0, 56, - 57, 0, 58, 59, 0, 0, 60, 0, 0, 61, - 0, 0, -244, 0, 0, 0, 0, 325, -244, 62, - 63, 64, 0, 10, 11, 324, 0, 35, 0, 36, - 0, 37, 0, 38, 39, 0, 0, 40, 0, 41, - 42, 112, 44, 45, 46, 0, 47, 48, 9, 0, - 0, 49, 50, 51, 52, 53, 54, 0, 0, 0, - 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 56, 57, 0, 58, 59, 0, 0, - 60, 0, 0, 61, 0, 35, -244, 642, 643, 37, - 160, 325, -244, 62, 63, 64, 0, 10, 11, 112, - 334, 0, 0, 0, 47, 48, 9, 0, 0, 0, - 335, 51, 0, 0, 0, 336, 337, 338, 158, 0, - 0, 0, 339, 0, 0, 0, 0, 0, 0, 340, - 0, 56, 57, 0, 58, 159, 0, 0, 60, 0, - 35, 61, 314, 0, 37, 0, 341, 0, 0, 0, - 0, 62, 63, 64, 112, 10, 11, 0, 342, 47, - 48, 9, 0, 0, 343, 0, 51, 11, 0, 0, - 0, 0, 0, 55, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 56, 57, 0, 58, - 59, 0, 0, 60, 0, 35, 61, 0, 0, 37, - 0, 0, 0, 0, 420, 0, 62, 63, 64, 112, - 10, 11, 0, 0, 47, 48, 9, 0, 0, 0, - 0, 51, 0, 429, 0, 0, 0, 0, 158, 0, + 56, 57, 0, 58, 59, 0, 0, 60, 0, 0, + 61, 0, 0, -249, 645, 646, 0, 160, 325, -249, + 62, 63, 64, 35, 10, 11, 421, 0, 37, 0, + 0, 0, 0, 0, 0, 0, 0, 112, 0, 334, + 0, 0, 47, 48, 9, 0, 0, 0, 335, 51, + 0, 0, 0, 336, 337, 338, 158, 0, 0, 0, + 339, 0, 0, 0, 0, 0, 0, 340, 0, 56, + 57, 0, 58, 159, 0, 0, 60, 0, 35, 61, + 314, 0, 0, 37, 341, 0, 0, 0, 0, 62, + 63, 64, 112, 10, 11, 0, 0, 47, 48, 9, + 0, 0, 343, 0, 51, 11, 0, 0, 0, 0, + 0, 55, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 56, 57, 0, 58, 59, 0, + 0, 60, 0, 35, 61, 0, 0, 0, 37, 0, + 0, 0, 420, 0, 62, 63, 64, 112, 10, 11, + 0, 0, 47, 48, 9, 0, 0, 0, 0, 51, + 0, 429, 0, 0, 0, 0, 158, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 56, + 57, 0, 58, 159, 0, 0, 60, 0, 35, 61, + 0, 0, 0, 37, 0, 0, 0, 0, 0, 62, + 63, 64, 112, 10, 11, 0, 0, 47, 48, 9, + 0, 473, 0, 0, 51, 0, 0, 0, 0, 0, + 0, 55, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 56, 57, 0, 58, 59, 0, + 0, 60, 0, 35, 61, 0, 0, 0, 37, 0, + 0, 0, 0, 0, 62, 63, 64, 112, 10, 11, + 0, 0, 47, 48, 9, 0, 474, 0, 0, 51, + 0, 0, 0, 0, 0, 0, 55, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 35, 0, 0, 56, + 57, 37, 58, 59, 0, 0, 60, 0, 0, 61, + 112, 0, 0, 0, 0, 47, 48, 9, 0, 62, + 63, 64, 51, 10, 11, 0, 0, 0, 0, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 56, 57, 0, 58, 159, 0, 0, 60, 0, - 35, 61, 0, 0, 37, 0, 0, 0, 0, 0, - 0, 62, 63, 64, 112, 10, 11, 0, 0, 47, - 48, 9, 0, 472, 0, 0, 51, 0, 0, 0, - 0, 0, 0, 55, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 56, 57, 0, 58, - 59, 0, 0, 60, 0, 35, 61, 0, 0, 37, - 0, 0, 0, 0, 0, 0, 62, 63, 64, 112, - 10, 11, 0, 0, 47, 48, 9, 0, 473, 0, - 0, 51, 0, 0, 0, 0, 0, 0, 55, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 56, 57, 0, 58, 59, 0, 0, 60, 0, - 35, 61, 0, 0, 37, 0, 0, 0, 0, 0, - 0, 62, 63, 64, 112, 10, 11, 0, 0, 47, - 48, 9, 0, 0, 0, 0, 51, 0, 0, 0, - 0, 0, 0, 55, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 56, 57, 0, 58, - 59, 0, 0, 60, 0, 35, 61, 0, 0, 37, - 0, 0, 0, 0, 0, 0, 62, 63, 64, 112, - 10, 11, 0, 0, 47, 48, 9, 0, 0, 0, - 0, 51, 0, 0, 0, 0, 0, 0, 158, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 56, 57, 0, 58, 159, 0, 0, 60, 0, - 35, 61, 0, 0, 283, 0, 0, 0, 0, 0, - 0, 62, 63, 64, 112, 10, 11, 0, 0, 47, - 48, 9, 0, 0, 0, 0, 51, 0, 0, 0, - 0, 0, 0, 55, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 56, 57, 0, 58, - 59, 0, 0, 60, 0, 0, 61, 0, 0, 37, - 0, 0, 0, 0, 0, 0, 62, 63, 64, 112, - 10, 11, 0, 0, 47, 48, 9, 0, 0, 0, - 0, 51, 0, 0, 0, 37, 0, 0, 224, 241, - 0, 0, 0, 37, 0, 112, 0, 0, 0, 0, - 47, 48, 9, 112, 0, 114, 0, 51, 47, 48, - 9, 225, 0, 0, 224, 51, 0, 290, 37, 0, - 0, 0, 113, 64, 0, 10, 11, 281, 112, 0, - 0, 114, 0, 47, 48, 9, 0, 225, 0, 114, - 51, 0, 0, 0, 0, 115, 37, 224, 0, 64, - 0, 10, 11, 0, 0, 0, 112, 64, 0, 10, - 11, 47, 48, 9, 114, 0, 0, 0, 51, 0, - 225, 37, 0, 0, 0, 406, 0, 0, 0, 283, - 0, 112, 64, 0, 10, 11, 47, 48, 9, 112, - 0, 0, 114, 51, 47, 48, 9, 0, 407, 0, - 224, 51, 0, 0, 334, 0, 0, 0, 224, 0, - 64, 0, 10, 11, 335, 0, 0, 114, 0, 336, - 337, 338, 0, 476, 0, 114, 339, 0, 0, 0, - 0, 225, 334, 439, 0, 64, 0, 10, 11, 0, - 0, 0, 335, 64, 0, 10, 11, 336, 337, 540, - 341, 0, 0, 0, 339, 0, 440, 334, 0, 0, - 0, 340, 0, 0, 0, 334, 0, 335, 343, 0, - 0, 11, 336, 337, 338, 335, 0, 0, 341, 339, - 336, 337, 338, 0, 0, 0, 340, 339, 0, 0, - 0, 0, 0, 0, 340, 0, 343, 0, 10, 11, - 0, 0, 0, 341, 0, 0, 0, 0, 0, 607, - 0, 341, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 343, 0, 0, 11, 0, 0, 0, 0, 343, - 176, 177, 11, 178, 0, 180, 181, 182, 0, 0, - 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, - 194, 195, 196, 197, 0, 0, 0, 0, 0, 0, - 176, 177, 0, 178, 0, 180, 181, 182, 0, 431, - 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, - 194, 195, 196, 197, 176, 177, 0, 178, 0, 180, - 181, 182, 0, 523, 184, 185, 186, 187, 188, 189, - 190, 191, 192, 193, 194, 195, 196, 197, 176, 177, - 0, 178, 0, 180, 181, 182, 0, 649, 184, 185, + 0, 0, 56, 57, 0, 58, 59, 0, 0, 60, + 0, 35, 61, 0, 0, 0, 37, 0, 0, 0, + 587, 0, 62, 63, 64, 112, 10, 11, 0, 0, + 47, 48, 9, 0, 0, 0, 0, 51, 0, 0, + 0, 0, 0, 0, 55, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 35, 0, 0, 56, 57, 37, + 58, 59, 0, 0, 60, 0, 0, 61, 112, 0, + 0, 0, 0, 47, 48, 9, 0, 62, 63, 64, + 51, 10, 11, 0, 0, 0, 0, 158, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, + 56, 57, 283, 58, 159, 0, 0, 60, 0, 0, + 61, 112, 0, 0, 0, 0, 47, 48, 9, 0, + 62, 63, 64, 51, 10, 11, 0, 0, 0, 0, + 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 56, 57, 37, 58, 59, 0, 0, + 60, 0, 0, 61, 112, 0, 0, 0, 0, 47, + 48, 9, 0, 62, 63, 64, 51, 10, 11, 0, + 37, 0, 0, 224, 0, 0, 0, 0, 37, 112, + 0, 0, 0, 0, 47, 48, 9, 112, 0, 0, + 114, 51, 47, 48, 9, 0, 225, 0, 113, 51, + 0, 0, 0, 0, 37, 0, 224, 0, 64, 0, + 10, 11, 396, 112, 0, 114, 0, 0, 47, 48, + 9, 115, 0, 114, 0, 51, 0, 0, 0, 225, + 0, 37, 406, 64, 0, 10, 11, 0, 0, 0, + 112, 64, 0, 10, 11, 47, 48, 9, 0, 114, + 0, 0, 51, 0, 0, 407, 0, 283, 0, 224, + 0, 0, 0, 0, 0, 334, 112, 64, 0, 10, + 11, 47, 48, 9, 335, 0, 114, 0, 51, 336, + 337, 338, 477, 0, 0, 224, 339, 0, 0, 0, + 334, 0, 0, 440, 64, 0, 10, 11, 334, 335, + 0, 460, 114, 0, 336, 337, 541, 335, 225, 0, + 341, 339, 336, 337, 338, 0, 441, 0, 340, 339, + 64, 0, 10, 11, 334, 0, 340, 0, 343, 0, + 0, 11, 0, 335, 0, 341, 0, 0, 336, 337, + 338, 0, 0, 341, 0, 339, 0, 0, 0, 0, + 0, 0, 340, 343, 0, 10, 11, 0, 0, 0, + 0, 343, 177, 0, 11, 0, 180, 181, 182, 341, + 0, 184, 185, 186, 187, 609, 189, 190, 191, 192, + 193, 194, 195, 196, 197, 0, 0, 343, 176, 177, + 11, 178, 0, 180, 181, 182, 0, 0, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, - 196, 197, 176, 177, 0, 178, 0, 180, 181, 182, - 0, 650, 184, 185, 186, 187, 188, 189, 190, 191, - 192, 193, 194, 195, 196, 197, 0, 176, 177, 434, - 178, 0, 180, 181, 182, 0, 0, 184, 185, 186, + 196, 197, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 176, 177, 0, 178, 0, 180, 181, 182, 0, + 434, 184, 185, 186, 187, 188, 189, 190, 191, 192, + 193, 194, 195, 196, 197, 0, 0, 0, 0, 0, + 0, 176, 177, 0, 178, 0, 180, 181, 182, 0, + 431, 184, 185, 186, 187, 188, 189, 190, 191, 192, + 193, 194, 195, 196, 197, 176, 177, 0, 178, 0, + 180, 181, 182, 0, 524, 184, 185, 186, 187, 188, + 189, 190, 191, 192, 193, 194, 195, 196, 197, 176, + 177, 0, 178, 0, 180, 181, 182, 0, 655, 184, + 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, + 195, 196, 197, 176, 177, 0, 178, 0, 180, 181, + 182, 0, 656, 184, 185, 186, 187, 188, 189, 190, + 191, 192, 193, 194, 195, 196, 197, 176, 177, 0, + 0, 0, 180, 181, 182, 0, 0, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 176, 177, 0, 0, 0, 180, 181, 182, 0, - 0, 184, 185, 186, 187, 188, 189, 190, 191, 192, - 193, 194, 195, 196, 197, 176, 177, 0, 0, 0, - 180, 181, 182, 0, 0, 184, 185, 186, 187, 0, - 189, 190, 191, 192, 193, 194, 195, 196, 197, 177, - 0, 0, 0, 180, 181, 182, 0, 0, 184, 185, - 186, 187, 0, 189, 190, 191, 192, 193, 194, 195, - 196, 197 + 0, 184, 185, 186, 187, 0, 189, 190, 191, 192, + 193, 194, 195, 196, 197 }; -#define yypact_value_is_default(yystate) \ - ((yystate) == (-551)) - -#define yytable_value_is_error(yytable_value) \ - YYID (0) - static const yytype_int16 yycheck[] = { - 5, 67, 250, 223, 37, 126, 37, 126, 143, 135, - 201, 132, 204, 147, 61, 20, 36, 22, 485, 39, - 31, 142, 28, 28, 321, 45, 452, 316, 323, 249, - 258, 36, 3, 11, 39, 24, 263, 264, 43, 267, - 45, 444, 67, 61, 594, 35, 0, 275, 53, 54, - 6, 279, 1, 3, 1, 3, 12, 3, 24, 35, - 59, 289, 67, 95, 63, 97, 98, 49, 3, 59, - 59, 35, 71, 25, 24, 37, 24, 67, 24, 3, - 37, 6, 24, 59, 389, 40, 35, 12, 35, 44, - 24, 67, 397, 59, 644, 106, 646, 75, 20, 61, - 24, 72, 50, 67, 61, 572, 172, 73, 74, 59, - 59, 59, 68, 63, 60, 135, 8, 63, 67, 53, - 67, 141, 127, 73, 74, 73, 74, 73, 74, 255, - 135, 73, 74, 8, 62, 424, 141, 426, 143, 63, - 437, 159, 147, 68, 126, 67, 25, 172, 62, 73, - 74, 113, 114, 115, 68, 460, 113, 114, 115, 24, - 6, 388, 382, 390, 3, 127, 12, 172, 21, 59, - 127, 62, 639, 65, 136, 63, 602, 68, 60, 136, - 24, 199, 144, 75, 74, 24, 8, 144, 436, 151, - 65, 66, 595, 75, 151, 200, 62, 159, 503, 62, - 75, 206, 159, 606, 607, 68, 35, 212, 113, 114, - 115, 50, 174, 62, 220, 220, 62, 174, 223, 68, - 515, 413, 68, 471, 62, 207, 208, 522, 420, 234, - 59, 136, 40, 24, 73, 74, 44, 199, 67, 144, - 3, 432, 199, 65, 249, 250, 151, 368, 3, 368, - 283, 51, 283, 75, 559, 71, 476, 378, 384, 378, - 62, 223, 67, 225, 399, 66, 223, 401, 225, 174, - 317, 576, 577, 66, 3, 59, 281, 523, 524, 241, - 59, 243, 24, 83, 241, 59, 243, 249, 74, 89, - 518, 3, 249, 24, 599, 7, 6, 64, 280, 317, - 62, 59, 12, 63, 75, 17, 59, 35, 290, 271, - 22, 23, 24, 67, 271, 60, 321, 29, 60, 59, - 225, 283, 35, 72, 286, 287, 283, 575, 72, 286, - 287, 73, 74, 62, 63, 3, 241, 342, 211, 68, - 24, 374, 60, 374, 217, 218, 59, 59, 353, 569, - 416, 7, 62, 60, 67, 317, 374, 24, 68, 71, - 317, 73, 74, 35, 384, 62, 271, 372, 60, 374, - 75, 62, 392, 35, 379, 59, 396, 382, 283, 384, - 427, 286, 287, 37, 366, 367, 53, 392, 24, 73, - 74, 396, 59, 59, 399, 35, 401, 59, 360, 62, - 3, 68, 72, 360, 62, 67, 73, 74, 65, 427, - 372, 416, 374, 62, 62, 372, 67, 374, 62, 59, - 382, 66, 65, 405, 386, 382, 59, 67, 67, 386, - 71, 436, 437, 67, 7, 65, 469, 419, 469, 444, - 445, 62, 447, 24, 406, 407, 567, 452, 567, 406, - 407, 469, 485, 458, 485, 360, 461, 462, 62, 113, - 114, 115, 62, 62, 60, 427, 471, 485, 341, 60, - 427, 476, 9, 127, 60, 24, 349, 495, 59, 63, - 17, 386, 136, 60, 21, 68, 24, 68, 60, 68, - 144, 35, 73, 74, 31, 32, 60, 151, 60, 60, - 75, 406, 407, 68, 53, 75, 60, 469, 60, 24, - 59, 68, 469, 60, 476, 36, 582, 3, 60, 476, - 174, 59, 62, 485, 73, 74, 72, 64, 485, 62, - 24, 59, 24, 495, 75, 73, 74, 60, 495, 572, - 66, 572, 60, 94, 95, 60, 97, 98, 55, 56, - 57, 58, 59, 60, 572, 62, 63, 519, 73, 74, - 60, 60, 519, 60, 569, 59, 439, 62, 60, 223, - 575, 225, 445, 446, 621, 448, 24, 582, 60, 73, - 74, 73, 74, 72, 457, 24, 459, 241, 60, 243, - 595, 59, 597, 59, 59, 249, 601, 602, 68, 62, - 62, 606, 607, 621, 68, 72, 639, 569, 639, 49, - 572, 59, 569, 62, 519, 572, 59, 271, 60, 14, - 59, 639, 68, 60, 68, 73, 74, 34, 49, 283, - 60, 62, 286, 287, 73, 74, 60, 44, 60, 31, - 61, 48, 60, 64, 60, 22, 53, 54, 55, 56, - 582, 158, 159, 508, 615, 377, 615, 142, 243, 621, - 211, 281, 524, 7, 621, 39, 217, 218, 159, 243, - 213, 7, 392, 17, 372, 548, 384, 639, 22, 23, - 24, 17, 639, 556, 22, 29, 22, 23, 24, 495, - 440, 601, 36, 29, 462, 597, 334, 334, 212, 458, - 36, -1, -1, -1, -1, -1, 360, -1, -1, 53, - -1, -1, -1, -1, -1, 59, -1, 53, 372, -1, - 374, 65, -1, 59, 597, 598, 34, 71, 382, 73, - 74, 75, 386, -1, -1, 71, 44, 73, 74, 75, + 5, 37, 61, 37, 142, 67, 223, 377, 143, 323, + 389, 126, 258, 250, 204, 20, 147, 22, 397, 135, + 126, 267, 28, 28, 201, 49, 132, 453, 31, 275, + 445, 36, 249, 279, 39, 321, 142, 3, 43, 67, + 45, 486, 11, 289, 5, 263, 264, 24, 53, 54, + 36, 316, 61, 39, 3, 37, 24, 322, 24, 45, + 25, 1, 67, 113, 114, 115, 20, 0, 24, 59, + 55, 56, 57, 58, 59, 60, 53, 62, 63, 61, + 25, 5, 461, 5, 74, 24, 136, 95, 24, 97, + 98, 59, 1, 59, 144, 35, 60, 63, 21, 3, + 62, 151, 126, 106, 65, 66, 75, 73, 74, 24, + 172, 75, 596, 67, 75, 35, 3, 73, 74, 59, + 3, 60, 127, 72, 174, 504, 35, 67, 573, 63, + 135, 113, 114, 115, 73, 74, 141, 24, 143, 255, + 71, 65, 147, 65, 172, 127, 62, 67, 62, 135, + 159, 75, 438, 75, 136, 141, 40, 62, 67, 424, + 44, 426, 144, 68, 648, 382, 650, 172, 3, 151, + 388, 24, 390, 158, 159, 225, 63, 159, 604, 62, + 63, 560, 597, 207, 208, 68, 73, 74, 51, 24, + 199, 241, 174, 608, 609, 200, 641, 62, 577, 578, + 437, 206, 516, 68, 40, 62, 62, 212, 44, 523, + 3, 68, 68, 3, 220, 220, 35, 199, 223, 62, + 83, 271, 601, 413, 3, 60, 89, 7, 63, 234, + 420, 24, 12, 283, 67, 472, 286, 287, 73, 74, + 59, 223, 66, 225, 249, 250, 66, 283, 67, 283, + 3, 35, 59, 368, 35, 432, 280, 50, 317, 241, + 477, 243, 368, 378, 399, 59, 290, 249, 384, 7, + 401, 24, 378, 519, 12, 59, 281, 59, 59, 74, + 73, 74, 62, 67, 24, 7, 67, 64, 68, 271, + 12, 661, 62, 3, 37, 24, 59, 50, 8, 63, + 59, 283, 67, 9, 286, 287, 59, 17, 317, 35, + 360, 17, 22, 23, 24, 21, 321, 631, 61, 29, + 73, 74, 7, 35, 62, 31, 32, 12, 35, 75, + 68, 60, 35, 59, 59, 317, 386, 342, 374, 576, + 374, 67, 366, 367, 73, 74, 68, 59, 353, 59, + 3, 60, 59, 570, 416, 67, 406, 407, 64, 72, + 67, 71, 60, 73, 74, 374, 8, 372, 427, 374, + 113, 114, 115, 72, 379, 35, 60, 382, 360, 384, + 62, 405, 75, 68, 127, 60, 62, 392, 24, 24, + 372, 396, 374, 136, 399, 419, 401, 587, 384, 62, + 382, 144, 59, 59, 386, 72, 392, 63, 151, 3, + 396, 416, 62, 62, 62, 71, 159, 53, 427, 65, + 67, 62, 65, 59, 406, 407, 66, 59, 67, 24, + 67, 174, 437, 438, 470, 8, 470, 73, 74, 65, + 445, 446, 71, 448, 62, 427, 62, 62, 453, 62, + 486, 60, 486, 568, 459, 60, 199, 462, 463, 60, + 63, 470, 568, 60, 59, 35, 24, 472, 24, 37, + 520, 60, 477, 68, 24, 68, 24, 486, 73, 74, + 223, 68, 225, 60, 24, 60, 60, 496, 470, 75, + 68, 75, 24, 60, 60, 477, 60, 53, 241, 60, + 243, 59, 36, 59, 486, 68, 249, 3, 62, 59, + 72, 59, 68, 60, 496, 73, 74, 73, 74, 59, + 24, 583, 660, 73, 74, 73, 74, 59, 271, 62, + 75, 59, 59, 73, 74, 60, 66, 573, 520, 573, + 283, 73, 74, 286, 287, 113, 114, 115, 94, 95, + 60, 97, 98, 60, 660, 60, 60, 60, 72, 127, + 62, 60, 60, 622, 573, 570, 24, 59, 136, 73, + 74, 576, 59, 68, 317, 72, 144, 62, 583, 68, + 62, 8, 49, 151, 62, 59, 14, 60, 570, 68, + 17, 573, 597, 68, 599, 22, 23, 24, 603, 604, + 34, 59, 29, 608, 609, 641, 174, 641, 60, 36, + 44, 60, 62, 622, 48, 73, 74, 360, 60, 53, + 54, 55, 56, 60, 60, 60, 53, 68, 31, 372, + 22, 374, 641, 583, 509, 642, 525, 525, 65, 382, + 622, 243, 39, 386, 71, 243, 211, 74, 281, 384, + 159, 392, 217, 218, 213, 223, 372, 225, 22, 641, + 334, 334, 496, 406, 407, 211, 441, 463, 603, 599, + 459, 217, 218, 241, 212, 243, -1, -1, -1, 8, + -1, 249, -1, -1, 427, -1, -1, -1, 17, -1, + -1, -1, -1, 22, 23, 24, -1, -1, -1, -1, + 29, -1, -1, 271, -1, -1, -1, 36, -1, -1, + -1, -1, -1, -1, 49, 283, -1, -1, 286, 287, + -1, -1, 4, 5, 53, -1, 61, 470, -1, 64, + 59, -1, -1, -1, 477, -1, 65, -1, -1, -1, + -1, -1, 71, 486, 73, 74, 75, -1, -1, -1, + -1, 33, 34, 496, 36, 37, 38, 39, 40, -1, + 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, + 52, 53, 54, 55, 56, -1, 341, 520, -1, -1, + -1, -1, -1, 65, 349, -1, -1, -1, 334, -1, + -1, -1, 360, 75, -1, 341, -1, -1, -1, -1, + -1, -1, -1, 349, 372, -1, 374, -1, -1, -1, + -1, -1, -1, -1, 382, -1, -1, -1, 386, -1, + -1, -1, -1, -1, -1, -1, -1, 570, -1, -1, + 573, -1, -1, -1, -1, -1, -1, -1, 406, 407, + 175, 176, 177, 178, -1, 180, 181, 182, -1, 184, + 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, + 195, 196, 197, -1, 199, -1, 201, -1, 203, -1, + -1, -1, 207, 208, 209, 440, -1, -1, -1, 622, + -1, 446, 447, -1, 449, -1, -1, -1, -1, -1, + -1, -1, -1, 458, 440, 460, -1, -1, 641, -1, + 446, 447, 470, 449, -1, -1, -1, -1, -1, 477, + -1, -1, 458, -1, 460, -1, -1, -1, 486, -1, + 8, -1, -1, 3, -1, -1, -1, -1, 8, 17, + -1, 11, -1, -1, 22, 23, 24, 17, -1, -1, + -1, 29, 22, 23, 24, 280, -1, -1, 36, 29, + -1, -1, 520, -1, -1, 290, 36, -1, -1, -1, + -1, -1, -1, -1, -1, 53, -1, -1, -1, 49, + 50, 59, 52, 53, -1, -1, 56, 65, 313, 59, + -1, -1, 317, 71, 549, 73, 74, 75, 323, 69, + 70, 71, 557, 73, 74, -1, -1, -1, 8, -1, + -1, 11, 570, 549, -1, 573, -1, 17, -1, -1, + -1, 557, 22, 23, 24, -1, -1, -1, 564, 29, + -1, -1, -1, -1, -1, -1, 36, -1, -1, -1, + -1, 366, 367, -1, 599, 600, -1, -1, -1, -1, + -1, -1, -1, 53, -1, -1, -1, -1, -1, 59, + 596, -1, -1, 599, 600, -1, -1, -1, -1, 0, + 1, 71, 3, 73, 74, 6, -1, 8, 9, 10, + 405, -1, 13, 641, 15, 16, 17, 18, 19, 20, + -1, 22, 23, 24, 419, -1, 27, 28, 29, 30, + 31, 32, 427, -1, -1, 36, -1, 432, -1, -1, + -1, -1, 648, -1, 650, -1, -1, -1, 49, 50, + -1, 52, 53, -1, -1, 56, -1, -1, 59, -1, + -1, 62, -1, -1, -1, -1, -1, -1, 69, 70, + 71, -1, 73, 74, -1, -1, -1, -1, 473, 474, + -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, + 3, -1, -1, 6, 7, 8, 9, 10, -1, 12, + 13, 496, 15, 16, 17, 18, 19, 20, -1, 22, + 23, 24, -1, -1, 27, 28, 29, 30, 31, 32, + -1, 516, -1, 36, -1, -1, -1, -1, 523, 524, + 525, -1, -1, -1, -1, -1, 49, 50, -1, 52, + 53, -1, -1, 56, -1, -1, 59, -1, -1, 62, + -1, -1, -1, -1, 67, 68, 69, 70, 71, -1, + 73, 74, 1, -1, 3, -1, -1, 6, -1, 8, + 9, 10, -1, -1, 13, -1, 15, 16, 17, 18, + 19, 20, -1, 22, 23, 24, 34, -1, 27, 28, + 29, 30, 31, 32, -1, -1, 44, 36, -1, -1, 48, 49, 50, 51, 52, 53, 54, 55, 56, -1, - -1, -1, 406, 407, 175, 176, 177, 178, -1, 180, - 181, 182, -1, 184, 185, 186, 187, 188, 189, 190, - 191, 192, 193, 194, 195, 196, 197, -1, 199, -1, - 201, -1, 203, 334, -1, -1, 207, 208, 209, -1, - 341, 7, -1, -1, -1, 11, -1, -1, 349, -1, - 4, 17, -1, -1, 8, -1, 22, 23, 24, -1, - -1, -1, -1, 29, -1, 469, -1, -1, -1, -1, - 36, -1, 476, -1, -1, -1, -1, -1, -1, 33, - 34, 485, 36, 37, 38, 39, 40, 53, 42, 43, - 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, - 54, 55, 56, -1, -1, 71, -1, -1, 74, 280, - -1, 65, -1, -1, -1, 519, -1, -1, -1, 290, - -1, 75, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 439, -1, - -1, -1, 313, -1, 445, 446, 317, 448, -1, -1, - -1, -1, 323, -1, 0, 1, 457, 3, 459, 5, - -1, 7, -1, 9, 10, 569, -1, 13, 572, 15, - 16, 17, 18, 19, 20, -1, 22, 23, 24, -1, - -1, 27, 28, 29, 30, 31, 32, -1, -1, -1, - 36, -1, -1, -1, -1, 366, 367, -1, -1, -1, - -1, -1, -1, 49, 50, -1, 52, 53, -1, -1, - 56, -1, -1, 59, -1, -1, 62, -1, 3, -1, - -1, -1, 7, 69, 70, 71, 11, 73, 74, -1, - -1, -1, 17, -1, 405, 639, -1, 22, 23, 24, - -1, -1, -1, -1, 29, -1, -1, 548, 419, -1, - -1, 36, -1, -1, -1, 556, 427, -1, -1, -1, - -1, 432, 563, -1, 49, 50, -1, 52, 53, -1, - -1, 56, -1, -1, 59, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 69, 70, 71, -1, 73, 74, - -1, -1, -1, 594, -1, -1, 597, 598, -1, -1, - -1, 472, 473, -1, -1, -1, -1, -1, -1, -1, - -1, 1, -1, 3, -1, 5, 6, 7, -1, 9, - 10, -1, 12, 13, 495, 15, 16, 17, 18, 19, - 20, -1, 22, 23, 24, -1, -1, 27, 28, 29, - 30, 31, 32, 644, 515, 646, 36, -1, -1, -1, - -1, 522, 523, 524, -1, -1, -1, -1, -1, 49, - 50, -1, 52, 53, -1, -1, 56, -1, -1, 59, - -1, -1, 62, -1, -1, -1, -1, 67, 68, 69, - 70, 71, -1, 73, 74, 1, -1, 3, -1, 5, - -1, 7, -1, 9, 10, -1, -1, 13, -1, 15, - 16, 17, 18, 19, 20, -1, 22, 23, 24, -1, - -1, 27, 28, 29, 30, 31, 32, -1, -1, -1, - 36, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 49, 50, -1, 52, 53, -1, -1, - 56, -1, -1, 59, -1, 3, 62, 618, 619, 7, - 621, 67, 68, 69, 70, 71, -1, 73, 74, 17, - 7, -1, -1, -1, 22, 23, 24, -1, -1, -1, - 17, 29, -1, -1, -1, 22, 23, 24, 36, -1, - -1, -1, 29, -1, -1, -1, -1, -1, -1, 36, - -1, 49, 50, -1, 52, 53, -1, -1, 56, -1, - 3, 59, 60, -1, 7, -1, 53, -1, -1, -1, - -1, 69, 70, 71, 17, 73, 74, -1, 65, 22, - 23, 24, -1, -1, 71, -1, 29, 74, -1, -1, - -1, -1, -1, 36, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 49, 50, -1, 52, - 53, -1, -1, 56, -1, 3, 59, -1, -1, 7, - -1, -1, -1, -1, 67, -1, 69, 70, 71, 17, - 73, 74, -1, -1, 22, 23, 24, -1, -1, -1, - -1, 29, -1, 31, -1, -1, -1, -1, 36, -1, + 49, 50, -1, 52, 53, -1, -1, 56, -1, -1, + 59, -1, -1, 62, 619, 620, -1, 622, 67, 68, + 69, 70, 71, 3, 73, 74, 631, -1, 8, -1, + -1, -1, -1, -1, -1, -1, -1, 17, -1, 8, + -1, -1, 22, 23, 24, -1, -1, -1, 17, 29, + -1, -1, -1, 22, 23, 24, 36, -1, -1, -1, + 29, -1, -1, -1, -1, -1, -1, 36, -1, 49, + 50, -1, 52, 53, -1, -1, 56, -1, 3, 59, + 60, -1, -1, 8, 53, -1, -1, -1, -1, 69, + 70, 71, 17, 73, 74, -1, -1, 22, 23, 24, + -1, -1, 71, -1, 29, 74, -1, -1, -1, -1, + -1, 36, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 49, 50, -1, 52, 53, -1, + -1, 56, -1, 3, 59, -1, -1, -1, 8, -1, + -1, -1, 67, -1, 69, 70, 71, 17, 73, 74, + -1, -1, 22, 23, 24, -1, -1, -1, -1, 29, + -1, 31, -1, -1, -1, -1, 36, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 49, + 50, -1, 52, 53, -1, -1, 56, -1, 3, 59, + -1, -1, -1, 8, -1, -1, -1, -1, -1, 69, + 70, 71, 17, 73, 74, -1, -1, 22, 23, 24, + -1, 26, -1, -1, 29, -1, -1, -1, -1, -1, + -1, 36, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 49, 50, -1, 52, 53, -1, + -1, 56, -1, 3, 59, -1, -1, -1, 8, -1, + -1, -1, -1, -1, 69, 70, 71, 17, 73, 74, + -1, -1, 22, 23, 24, -1, 26, -1, -1, 29, + -1, -1, -1, -1, -1, -1, 36, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 3, -1, -1, 49, + 50, 8, 52, 53, -1, -1, 56, -1, -1, 59, + 17, -1, -1, -1, -1, 22, 23, 24, -1, 69, + 70, 71, 29, 73, 74, -1, -1, -1, -1, 36, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 49, 50, -1, 52, 53, -1, -1, 56, -1, - 3, 59, -1, -1, 7, -1, -1, -1, -1, -1, - -1, 69, 70, 71, 17, 73, 74, -1, -1, 22, - 23, 24, -1, 26, -1, -1, 29, -1, -1, -1, - -1, -1, -1, 36, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 49, 50, -1, 52, - 53, -1, -1, 56, -1, 3, 59, -1, -1, 7, - -1, -1, -1, -1, -1, -1, 69, 70, 71, 17, - 73, 74, -1, -1, 22, 23, 24, -1, 26, -1, - -1, 29, -1, -1, -1, -1, -1, -1, 36, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 49, 50, -1, 52, 53, -1, -1, 56, -1, - 3, 59, -1, -1, 7, -1, -1, -1, -1, -1, - -1, 69, 70, 71, 17, 73, 74, -1, -1, 22, - 23, 24, -1, -1, -1, -1, 29, -1, -1, -1, - -1, -1, -1, 36, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 49, 50, -1, 52, - 53, -1, -1, 56, -1, 3, 59, -1, -1, 7, - -1, -1, -1, -1, -1, -1, 69, 70, 71, 17, - 73, 74, -1, -1, 22, 23, 24, -1, -1, -1, - -1, 29, -1, -1, -1, -1, -1, -1, 36, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 49, 50, -1, 52, 53, -1, -1, 56, -1, - 3, 59, -1, -1, 7, -1, -1, -1, -1, -1, - -1, 69, 70, 71, 17, 73, 74, -1, -1, 22, - 23, 24, -1, -1, -1, -1, 29, -1, -1, -1, - -1, -1, -1, 36, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 49, 50, -1, 52, - 53, -1, -1, 56, -1, -1, 59, -1, -1, 7, - -1, -1, -1, -1, -1, -1, 69, 70, 71, 17, - 73, 74, -1, -1, 22, 23, 24, -1, -1, -1, - -1, 29, -1, -1, -1, 7, -1, -1, 36, 11, - -1, -1, -1, 7, -1, 17, -1, -1, -1, -1, - 22, 23, 24, 17, -1, 53, -1, 29, 22, 23, - 24, 59, -1, -1, 36, 29, -1, 65, 7, -1, - -1, -1, 36, 71, -1, 73, 74, 75, 17, -1, - -1, 53, -1, 22, 23, 24, -1, 59, -1, 53, - 29, -1, -1, -1, -1, 59, 7, 36, -1, 71, - -1, 73, 74, -1, -1, -1, 17, 71, -1, 73, - 74, 22, 23, 24, 53, -1, -1, -1, 29, -1, - 59, 7, -1, -1, -1, 36, -1, -1, -1, 7, - -1, 17, 71, -1, 73, 74, 22, 23, 24, 17, - -1, -1, 53, 29, 22, 23, 24, -1, 59, -1, - 36, 29, -1, -1, 7, -1, -1, -1, 36, -1, - 71, -1, 73, 74, 17, -1, -1, 53, -1, 22, - 23, 24, -1, 59, -1, 53, 29, -1, -1, -1, - -1, 59, 7, 36, -1, 71, -1, 73, 74, -1, - -1, -1, 17, 71, -1, 73, 74, 22, 23, 24, - 53, -1, -1, -1, 29, -1, 59, 7, -1, -1, - -1, 36, -1, -1, -1, 7, -1, 17, 71, -1, - -1, 74, 22, 23, 24, 17, -1, -1, 53, 29, - 22, 23, 24, -1, -1, -1, 36, 29, -1, -1, - -1, -1, -1, -1, 36, -1, 71, -1, 73, 74, - -1, -1, -1, 53, -1, -1, -1, -1, -1, 59, - -1, 53, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 71, -1, -1, 74, -1, -1, -1, -1, 71, - 33, 34, 74, 36, -1, 38, 39, 40, -1, -1, - 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, - 53, 54, 55, 56, -1, -1, -1, -1, -1, -1, - 33, 34, -1, 36, -1, 38, 39, 40, -1, 72, - 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, - 53, 54, 55, 56, 33, 34, -1, 36, -1, 38, - 39, 40, -1, 66, 43, 44, 45, 46, 47, 48, - 49, 50, 51, 52, 53, 54, 55, 56, 33, 34, - -1, 36, -1, 38, 39, 40, -1, 66, 43, 44, + -1, -1, 49, 50, -1, 52, 53, -1, -1, 56, + -1, 3, 59, -1, -1, -1, 8, -1, -1, -1, + 67, -1, 69, 70, 71, 17, 73, 74, -1, -1, + 22, 23, 24, -1, -1, -1, -1, 29, -1, -1, + -1, -1, -1, -1, 36, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 3, -1, -1, 49, 50, 8, + 52, 53, -1, -1, 56, -1, -1, 59, 17, -1, + -1, -1, -1, 22, 23, 24, -1, 69, 70, 71, + 29, 73, 74, -1, -1, -1, -1, 36, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 3, -1, -1, + 49, 50, 8, 52, 53, -1, -1, 56, -1, -1, + 59, 17, -1, -1, -1, -1, 22, 23, 24, -1, + 69, 70, 71, 29, 73, 74, -1, -1, -1, -1, + 36, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 49, 50, 8, 52, 53, -1, -1, + 56, -1, -1, 59, 17, -1, -1, -1, -1, 22, + 23, 24, -1, 69, 70, 71, 29, 73, 74, -1, + 8, -1, -1, 36, -1, -1, -1, -1, 8, 17, + -1, -1, -1, -1, 22, 23, 24, 17, -1, -1, + 53, 29, 22, 23, 24, -1, 59, -1, 36, 29, + -1, -1, -1, -1, 8, -1, 36, -1, 71, -1, + 73, 74, 75, 17, -1, 53, -1, -1, 22, 23, + 24, 59, -1, 53, -1, 29, -1, -1, -1, 59, + -1, 8, 36, 71, -1, 73, 74, -1, -1, -1, + 17, 71, -1, 73, 74, 22, 23, 24, -1, 53, + -1, -1, 29, -1, -1, 59, -1, 8, -1, 36, + -1, -1, -1, -1, -1, 8, 17, 71, -1, 73, + 74, 22, 23, 24, 17, -1, 53, -1, 29, 22, + 23, 24, 59, -1, -1, 36, 29, -1, -1, -1, + 8, -1, -1, 36, 71, -1, 73, 74, 8, 17, + -1, 11, 53, -1, 22, 23, 24, 17, 59, -1, + 53, 29, 22, 23, 24, -1, 59, -1, 36, 29, + 71, -1, 73, 74, 8, -1, 36, -1, 71, -1, + -1, 74, -1, 17, -1, 53, -1, -1, 22, 23, + 24, -1, -1, 53, -1, 29, -1, -1, -1, -1, + -1, -1, 36, 71, -1, 73, 74, -1, -1, -1, + -1, 71, 34, -1, 74, -1, 38, 39, 40, 53, + -1, 43, 44, 45, 46, 59, 48, 49, 50, 51, + 52, 53, 54, 55, 56, -1, -1, 71, 33, 34, + 74, 36, -1, 38, 39, 40, -1, -1, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, - 55, 56, 33, 34, -1, 36, -1, 38, 39, 40, - -1, 66, 43, 44, 45, 46, 47, 48, 49, 50, - 51, 52, 53, 54, 55, 56, -1, 33, 34, 60, - 36, -1, 38, 39, 40, -1, -1, 43, 44, 45, + 55, 56, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 33, 34, -1, 36, -1, 38, 39, 40, -1, + 75, 43, 44, 45, 46, 47, 48, 49, 50, 51, + 52, 53, 54, 55, 56, -1, -1, -1, -1, -1, + -1, 33, 34, -1, 36, -1, 38, 39, 40, -1, + 72, 43, 44, 45, 46, 47, 48, 49, 50, 51, + 52, 53, 54, 55, 56, 33, 34, -1, 36, -1, + 38, 39, 40, -1, 66, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 33, + 34, -1, 36, -1, 38, 39, 40, -1, 66, 43, + 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, + 54, 55, 56, 33, 34, -1, 36, -1, 38, 39, + 40, -1, 66, 43, 44, 45, 46, 47, 48, 49, + 50, 51, 52, 53, 54, 55, 56, 33, 34, -1, + -1, -1, 38, 39, 40, -1, -1, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 33, 34, -1, -1, -1, 38, 39, 40, -1, - -1, 43, 44, 45, 46, 47, 48, 49, 50, 51, - 52, 53, 54, 55, 56, 33, 34, -1, -1, -1, - 38, 39, 40, -1, -1, 43, 44, 45, 46, -1, - 48, 49, 50, 51, 52, 53, 54, 55, 56, 34, - -1, -1, -1, 38, 39, 40, -1, -1, 43, 44, - 45, 46, -1, 48, 49, 50, 51, 52, 53, 54, - 55, 56 + -1, 43, 44, 45, 46, -1, 48, 49, 50, 51, + 52, 53, 54, 55, 56 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing @@ -1488,71 +1485,72 @@ static const yytype_int16 yycheck[] = static const yytype_uint8 yystos[] = { 0, 77, 79, 80, 0, 25, 78, 25, 86, 24, - 73, 74, 137, 138, 81, 24, 88, 89, 3, 62, - 21, 82, 162, 24, 87, 210, 63, 3, 59, 63, - 83, 85, 137, 62, 1, 3, 5, 7, 9, 10, + 73, 74, 141, 142, 81, 24, 88, 89, 3, 62, + 21, 82, 166, 24, 87, 214, 63, 3, 59, 63, + 83, 85, 141, 62, 1, 3, 6, 8, 9, 10, 13, 15, 16, 17, 18, 19, 20, 22, 23, 27, 28, 29, 30, 31, 32, 36, 49, 50, 52, 53, 56, 59, 69, 70, 71, 90, 91, 92, 98, 110, - 113, 118, 121, 123, 124, 125, 126, 130, 134, 137, - 139, 140, 145, 146, 149, 152, 153, 154, 157, 160, - 161, 177, 182, 62, 9, 17, 21, 31, 32, 64, - 195, 24, 60, 83, 84, 3, 86, 88, 3, 134, - 136, 137, 17, 36, 53, 59, 137, 139, 144, 148, - 149, 150, 157, 136, 125, 130, 111, 59, 137, 155, - 125, 134, 114, 35, 67, 133, 71, 123, 182, 189, - 122, 133, 119, 59, 96, 97, 137, 59, 93, 135, - 137, 181, 124, 124, 124, 124, 124, 124, 36, 53, - 123, 131, 143, 149, 151, 157, 124, 124, 11, 123, - 188, 62, 59, 94, 181, 4, 33, 34, 36, 37, + 113, 121, 124, 126, 127, 128, 129, 134, 138, 141, + 143, 144, 149, 150, 153, 156, 157, 158, 161, 164, + 165, 181, 186, 62, 9, 17, 21, 31, 32, 64, + 199, 24, 60, 83, 84, 3, 86, 88, 3, 138, + 140, 141, 17, 36, 53, 59, 141, 143, 148, 152, + 153, 154, 161, 140, 128, 134, 111, 59, 141, 159, + 128, 138, 114, 35, 67, 137, 71, 126, 186, 193, + 125, 137, 122, 59, 96, 97, 141, 59, 93, 139, + 141, 185, 127, 127, 127, 127, 127, 127, 36, 53, + 126, 135, 147, 153, 155, 161, 127, 127, 11, 126, + 192, 62, 59, 94, 185, 4, 33, 34, 36, 37, 38, 39, 40, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 67, 59, - 63, 71, 66, 59, 133, 1, 133, 8, 65, 75, - 138, 196, 59, 156, 196, 24, 196, 197, 196, 64, - 62, 186, 88, 59, 36, 59, 142, 148, 149, 150, - 151, 157, 142, 142, 63, 98, 107, 108, 109, 182, - 190, 11, 132, 137, 141, 142, 173, 174, 175, 59, - 67, 158, 112, 190, 24, 59, 68, 134, 167, 169, - 171, 142, 35, 53, 59, 68, 134, 166, 168, 169, - 170, 180, 112, 60, 97, 165, 142, 60, 93, 163, - 65, 75, 142, 7, 143, 60, 72, 72, 60, 94, - 65, 142, 123, 123, 123, 123, 123, 123, 123, 123, - 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, - 123, 123, 123, 127, 60, 131, 183, 59, 137, 123, - 188, 178, 123, 127, 1, 67, 91, 100, 176, 177, - 179, 182, 182, 123, 7, 17, 22, 23, 24, 29, - 36, 53, 65, 71, 138, 198, 200, 201, 202, 137, - 203, 211, 158, 59, 3, 198, 198, 83, 60, 175, - 7, 142, 60, 137, 35, 105, 8, 65, 62, 142, - 132, 141, 75, 187, 60, 175, 179, 115, 62, 63, - 24, 169, 59, 172, 62, 186, 72, 104, 59, 170, - 53, 170, 62, 186, 3, 194, 75, 142, 120, 62, - 186, 62, 186, 182, 135, 65, 36, 59, 142, 148, - 149, 150, 157, 67, 142, 142, 62, 186, 182, 65, - 67, 123, 128, 129, 184, 185, 11, 75, 187, 31, - 131, 72, 66, 176, 60, 185, 101, 62, 68, 36, - 59, 199, 200, 202, 59, 67, 71, 67, 7, 198, - 3, 50, 59, 137, 208, 209, 3, 72, 65, 11, - 198, 60, 75, 62, 191, 211, 62, 62, 62, 60, - 60, 106, 26, 26, 190, 173, 59, 137, 147, 148, - 149, 150, 151, 157, 159, 60, 68, 105, 190, 137, - 60, 175, 171, 68, 142, 6, 12, 68, 99, 102, - 170, 194, 170, 60, 168, 68, 134, 194, 35, 97, - 60, 93, 60, 182, 142, 127, 94, 95, 164, 181, - 60, 182, 127, 66, 75, 187, 68, 75, 187, 131, - 60, 60, 60, 188, 68, 179, 176, 198, 201, 191, - 24, 137, 138, 193, 198, 205, 213, 198, 137, 192, - 204, 212, 198, 3, 208, 62, 72, 198, 209, 198, - 194, 137, 203, 60, 179, 123, 123, 62, 175, 59, - 159, 116, 60, 183, 66, 103, 60, 60, 194, 104, - 60, 185, 62, 186, 142, 185, 123, 129, 128, 129, - 60, 72, 68, 60, 60, 59, 68, 62, 72, 198, - 68, 62, 49, 198, 62, 194, 59, 59, 198, 206, - 207, 68, 190, 60, 175, 14, 117, 159, 8, 65, - 66, 75, 179, 194, 194, 68, 68, 95, 60, 68, - 206, 191, 205, 198, 194, 204, 208, 191, 191, 60, - 100, 113, 123, 123, 60, 60, 60, 60, 159, 66, - 66, 206, 206 + 63, 71, 66, 59, 137, 1, 137, 5, 65, 75, + 142, 200, 59, 160, 200, 24, 200, 201, 200, 64, + 62, 190, 88, 59, 36, 59, 146, 152, 153, 154, + 155, 161, 146, 146, 63, 98, 107, 108, 109, 186, + 194, 11, 136, 141, 145, 146, 177, 178, 179, 59, + 67, 162, 112, 194, 24, 59, 68, 138, 171, 173, + 175, 146, 35, 53, 59, 68, 138, 170, 172, 173, + 174, 184, 112, 60, 97, 169, 146, 60, 93, 167, + 65, 75, 146, 8, 147, 60, 72, 72, 60, 94, + 65, 146, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 130, 60, 135, 187, 59, 141, 126, + 192, 182, 126, 130, 1, 67, 91, 100, 180, 181, + 183, 186, 186, 126, 8, 17, 22, 23, 24, 29, + 36, 53, 65, 71, 142, 202, 204, 205, 206, 141, + 207, 215, 162, 59, 3, 202, 202, 83, 60, 179, + 8, 146, 60, 141, 35, 105, 5, 65, 62, 146, + 136, 145, 75, 191, 60, 179, 183, 115, 62, 63, + 24, 173, 59, 176, 62, 190, 72, 104, 59, 174, + 53, 174, 62, 190, 3, 198, 75, 146, 123, 62, + 190, 62, 190, 186, 139, 65, 36, 59, 146, 152, + 153, 154, 161, 67, 146, 146, 62, 190, 186, 65, + 67, 126, 131, 132, 188, 189, 11, 75, 191, 31, + 135, 72, 66, 180, 75, 191, 189, 101, 62, 68, + 36, 59, 203, 204, 206, 59, 67, 71, 67, 8, + 202, 3, 50, 59, 141, 212, 213, 3, 72, 65, + 11, 202, 60, 75, 62, 195, 215, 62, 62, 62, + 60, 60, 106, 26, 26, 194, 177, 59, 141, 151, + 152, 153, 154, 155, 161, 163, 60, 68, 105, 194, + 141, 60, 179, 175, 68, 146, 7, 12, 68, 99, + 102, 174, 198, 174, 60, 172, 68, 138, 198, 35, + 97, 60, 93, 60, 186, 146, 130, 94, 95, 168, + 185, 60, 186, 130, 66, 75, 191, 68, 191, 135, + 60, 60, 60, 192, 60, 68, 183, 180, 202, 205, + 195, 24, 141, 142, 197, 202, 209, 217, 202, 141, + 196, 208, 216, 202, 3, 212, 62, 72, 202, 213, + 202, 198, 141, 207, 60, 183, 126, 126, 62, 179, + 59, 163, 116, 60, 187, 66, 103, 60, 60, 198, + 104, 60, 189, 62, 190, 146, 189, 67, 126, 133, + 131, 132, 60, 72, 68, 60, 60, 59, 68, 62, + 72, 202, 68, 62, 49, 202, 62, 198, 59, 59, + 202, 210, 211, 68, 194, 60, 179, 119, 163, 5, + 65, 66, 75, 183, 198, 198, 68, 68, 95, 60, + 68, 130, 210, 195, 209, 202, 198, 208, 212, 195, + 195, 60, 14, 117, 120, 126, 126, 189, 60, 60, + 60, 60, 163, 20, 100, 66, 66, 68, 210, 210, + 118, 112, 105 }; #define yyerrok (yyerrstatus = 0) @@ -1567,18 +1565,9 @@ static const yytype_uint8 yystos[] = /* Like YYERROR except do call yyerror. This remains here temporarily to ease the transition to the new meaning of YYERROR, for GCC. - Once GCC version 2 has supplanted version 1, this can go. However, - YYFAIL appears to be in use. Nevertheless, it is formally deprecated - in Bison 2.4.2's NEWS entry, where a plan to phase it out is - discussed. */ + Once GCC version 2 has supplanted version 1, this can go. */ #define YYFAIL goto yyerrlab -#if defined YYFAIL - /* This is here to suppress warnings from the GCC cpp's - -Wunused-macros. Normally we don't worry about that warning, but - some users do, and we want to make it easy for users to remove - YYFAIL uses, which will produce warnings from Bison 2.5. */ -#endif #define YYRECOVERING() (!!yyerrstatus) @@ -1588,6 +1577,7 @@ do \ { \ yychar = (Token); \ yylval = (Value); \ + yytoken = YYTRANSLATE (yychar); \ YYPOPSTACK (1); \ goto yybackup; \ } \ @@ -1629,10 +1619,19 @@ while (YYID (0)) #endif -/* This macro is provided for backward compatibility. */ +/* YY_LOCATION_PRINT -- Print the location on the stream. + This macro was not mandated originally: define only if we know + we won't break user code: when these are the locations we know. */ #ifndef YY_LOCATION_PRINT -# define YY_LOCATION_PRINT(File, Loc) ((void) 0) +# if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL +# define YY_LOCATION_PRINT(File, Loc) \ + fprintf (File, "%d.%d-%d.%d", \ + (Loc).first_line, (Loc).first_column, \ + (Loc).last_line, (Loc).last_column) +# else +# define YY_LOCATION_PRINT(File, Loc) ((void) 0) +# endif #endif @@ -1736,20 +1735,17 @@ yy_symbol_print (yyoutput, yytype, yyvaluep) #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void -yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) +yy_stack_print (yytype_int16 *bottom, yytype_int16 *top) #else static void -yy_stack_print (yybottom, yytop) - yytype_int16 *yybottom; - yytype_int16 *yytop; +yy_stack_print (bottom, top) + yytype_int16 *bottom; + yytype_int16 *top; #endif { YYFPRINTF (stderr, "Stack now"); - for (; yybottom <= yytop; yybottom++) - { - int yybot = *yybottom; - YYFPRINTF (stderr, " %d", yybot); - } + for (; bottom <= top; ++bottom) + YYFPRINTF (stderr, " %d", *bottom); YYFPRINTF (stderr, "\n"); } @@ -1783,11 +1779,11 @@ yy_reduce_print (yyvsp, yyrule) /* The symbols being reduced. */ for (yyi = 0; yyi < yynrhs; yyi++) { - YYFPRINTF (stderr, " $%d = ", yyi + 1); + fprintf (stderr, " $%d = ", yyi + 1); yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], &(yyvsp[(yyi + 1) - (yynrhs)]) ); - YYFPRINTF (stderr, "\n"); + fprintf (stderr, "\n"); } } @@ -1824,6 +1820,7 @@ int yydebug; # define YYMAXDEPTH 10000 #endif + #if YYERROR_VERBOSE @@ -1926,142 +1923,115 @@ yytnamerr (char *yyres, const char *yystr) } # endif -/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message - about the unexpected token YYTOKEN for the state stack whose top is - YYSSP. - - Return 0 if *YYMSG was successfully written. Return 1 if *YYMSG is - not large enough to hold the message. In that case, also set - *YYMSG_ALLOC to the required number of bytes. Return 2 if the - required number of bytes is too large to store. */ -static int -yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, - yytype_int16 *yyssp, int yytoken) +/* Copy into YYRESULT an error message about the unexpected token + YYCHAR while in state YYSTATE. Return the number of bytes copied, + including the terminating null byte. If YYRESULT is null, do not + copy anything; just return the number of bytes that would be + copied. As a special case, return 0 if an ordinary "syntax error" + message will do. Return YYSIZE_MAXIMUM if overflow occurs during + size calculation. */ +static YYSIZE_T +yysyntax_error (char *yyresult, int yystate, int yychar) { - YYSIZE_T yysize0 = yytnamerr (0, yytname[yytoken]); - YYSIZE_T yysize = yysize0; - YYSIZE_T yysize1; - enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; - /* Internationalized format string. */ - const char *yyformat = 0; - /* Arguments of yyformat. */ - char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; - /* Number of reported tokens (one for the "unexpected", one per - "expected"). */ - int yycount = 0; - - /* There are many possibilities here to consider: - - Assume YYFAIL is not used. It's too flawed to consider. See - <http://lists.gnu.org/archive/html/bison-patches/2009-12/msg00024.html> - for details. YYERROR is fine as it does not invoke this - function. - - If this state is a consistent state with a default action, then - the only way this function was invoked is if the default action - is an error action. In that case, don't check for expected - tokens because there are none. - - The only way there can be no lookahead present (in yychar) is if - this state is a consistent state with a default action. Thus, - detecting the absence of a lookahead is sufficient to determine - that there is no unexpected or expected token to report. In that - case, just report a simple "syntax error". - - Don't assume there isn't a lookahead just because this state is a - consistent state with a default action. There might have been a - previous inconsistent state, consistent state with a non-default - action, or user semantic action that manipulated yychar. - - Of course, the expected token list depends on states to have - correct lookahead information, and it depends on the parser not - to perform extra reductions after fetching a lookahead from the - scanner and before detecting a syntax error. Thus, state merging - (from LALR or IELR) and default reductions corrupt the expected - token list. However, the list is correct for canonical LR with - one exception: it will still contain any token that will not be - accepted due to an error action in a later state. - */ - if (yytoken != YYEMPTY) - { - int yyn = yypact[*yyssp]; - yyarg[yycount++] = yytname[yytoken]; - if (!yypact_value_is_default (yyn)) - { - /* Start YYX at -YYN if negative to avoid negative indexes in - YYCHECK. In other words, skip the first -YYN actions for - this state because they are default actions. */ - int yyxbegin = yyn < 0 ? -yyn : 0; - /* Stay within bounds of both yycheck and yytname. */ - int yychecklim = YYLAST - yyn + 1; - int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; - int yyx; - - for (yyx = yyxbegin; yyx < yyxend; ++yyx) - if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR - && !yytable_value_is_error (yytable[yyx + yyn])) - { - if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) - { - yycount = 1; - yysize = yysize0; - break; - } - yyarg[yycount++] = yytname[yyx]; - yysize1 = yysize + yytnamerr (0, yytname[yyx]); - if (! (yysize <= yysize1 - && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) - return 2; - yysize = yysize1; - } - } - } + int yyn = yypact[yystate]; - switch (yycount) - { -# define YYCASE_(N, S) \ - case N: \ - yyformat = S; \ - break - YYCASE_(0, YY_("syntax error")); - YYCASE_(1, YY_("syntax error, unexpected %s")); - YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s")); - YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s")); - YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s")); - YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s")); -# undef YYCASE_ - } + if (! (YYPACT_NINF < yyn && yyn <= YYLAST)) + return 0; + else + { + int yytype = YYTRANSLATE (yychar); + YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]); + YYSIZE_T yysize = yysize0; + YYSIZE_T yysize1; + int yysize_overflow = 0; + enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; + char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; + int yyx; + +# if 0 + /* This is so xgettext sees the translatable formats that are + constructed on the fly. */ + YY_("syntax error, unexpected %s"); + YY_("syntax error, unexpected %s, expecting %s"); + YY_("syntax error, unexpected %s, expecting %s or %s"); + YY_("syntax error, unexpected %s, expecting %s or %s or %s"); + YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"); +# endif + char *yyfmt; + char const *yyf; + static char const yyunexpected[] = "syntax error, unexpected %s"; + static char const yyexpecting[] = ", expecting %s"; + static char const yyor[] = " or %s"; + char yyformat[sizeof yyunexpected + + sizeof yyexpecting - 1 + + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2) + * (sizeof yyor - 1))]; + char const *yyprefix = yyexpecting; + + /* Start YYX at -YYN if negative to avoid negative indexes in + YYCHECK. */ + int yyxbegin = yyn < 0 ? -yyn : 0; + + /* Stay within bounds of both yycheck and yytname. */ + int yychecklim = YYLAST - yyn + 1; + int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; + int yycount = 1; + + yyarg[0] = yytname[yytype]; + yyfmt = yystpcpy (yyformat, yyunexpected); + + for (yyx = yyxbegin; yyx < yyxend; ++yyx) + if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) + { + if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) + { + yycount = 1; + yysize = yysize0; + yyformat[sizeof yyunexpected - 1] = '\0'; + break; + } + yyarg[yycount++] = yytname[yyx]; + yysize1 = yysize + yytnamerr (0, yytname[yyx]); + yysize_overflow |= (yysize1 < yysize); + yysize = yysize1; + yyfmt = yystpcpy (yyfmt, yyprefix); + yyprefix = yyor; + } - yysize1 = yysize + yystrlen (yyformat); - if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) - return 2; - yysize = yysize1; + yyf = YY_(yyformat); + yysize1 = yysize + yystrlen (yyf); + yysize_overflow |= (yysize1 < yysize); + yysize = yysize1; - if (*yymsg_alloc < yysize) - { - *yymsg_alloc = 2 * yysize; - if (! (yysize <= *yymsg_alloc - && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM)) - *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM; - return 1; - } + if (yysize_overflow) + return YYSIZE_MAXIMUM; - /* Avoid sprintf, as that infringes on the user's name space. - Don't have undefined behavior even if the translation - produced a string with the wrong number of "%s"s. */ - { - char *yyp = *yymsg; - int yyi = 0; - while ((*yyp = *yyformat) != '\0') - if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount) - { - yyp += yytnamerr (yyp, yyarg[yyi++]); - yyformat += 2; - } - else - { - yyp++; - yyformat++; - } - } - return 0; + if (yyresult) + { + /* Avoid sprintf, as that infringes on the user's name space. + Don't have undefined behavior even if the translation + produced a string with the wrong number of "%s"s. */ + char *yyp = yyresult; + int yyi = 0; + while ((*yyp = *yyf) != '\0') + { + if (*yyp == '%' && yyf[1] == 's' && yyi < yycount) + { + yyp += yytnamerr (yyp, yyarg[yyi++]); + yyf += 2; + } + else + { + yyp++; + yyf++; + } + } + } + return yysize; + } } #endif /* YYERROR_VERBOSE */ + /*-----------------------------------------------. | Release the memory associated to this symbol. | @@ -2093,9 +2063,10 @@ yydestruct (yymsg, yytype, yyvaluep) break; } } - + /* Prevent warnings from -Wmissing-prototypes. */ + #ifdef YYPARSE_PARAM #if defined __STDC__ || defined __cplusplus int yyparse (void *YYPARSE_PARAM); @@ -2111,16 +2082,18 @@ int yyparse (); #endif /* ! YYPARSE_PARAM */ -/* The lookahead symbol. */ + +/* The look-ahead symbol. */ int yychar, yystate; -/* The semantic value of the lookahead symbol. */ +/* The semantic value of the look-ahead symbol. */ YYSTYPE yylval; /* Number of syntax errors so far. */ int yynerrs; + /*----------. | yyparse. | `----------*/ @@ -2147,36 +2120,13 @@ yyparse () #endif #endif { - /* Number of tokens to shift before error messages enabled. */ - int yyerrstatus; - - /* The stacks and their tools: - `yyss': related to states. - `yyvs': related to semantic values. - - Refer to the stacks thru separate pointers, to allow yyoverflow - to reallocate them elsewhere. */ - - /* The state stack. */ - yytype_int16 yyssa[YYINITDEPTH]; - yytype_int16 *yyss; - yytype_int16 *yyssp; - - /* The semantic value stack. */ - YYSTYPE yyvsa[YYINITDEPTH]; - YYSTYPE *yyvs; - YYSTYPE *yyvsp; - - YYSIZE_T yystacksize; - + int yyn; int yyresult; - /* Lookahead token as an internal (translated) token number. */ - int yytoken; - /* The variables used to return semantic value and location from the - action routines. */ - YYSTYPE yyval; - + /* Number of tokens to shift before error messages enabled. */ + int yyerrstatus; + /* Look-ahead token as an internal (translated) token number. */ + int yytoken = 0; #if YYERROR_VERBOSE /* Buffer for error messages, and its allocated size. */ char yymsgbuf[128]; @@ -2184,28 +2134,51 @@ yyparse () YYSIZE_T yymsg_alloc = sizeof yymsgbuf; #endif + /* Three stacks and their tools: + `yyss': related to states, + `yyvs': related to semantic values, + `yyls': related to locations. + + Refer to the stacks thru separate pointers, to allow yyoverflow + to reallocate them elsewhere. */ + + /* The state stack. */ + yytype_int16 yyssa[YYINITDEPTH]; + yytype_int16 *yyss = yyssa; + yytype_int16 *yyssp; + + /* The semantic value stack. */ + YYSTYPE yyvsa[YYINITDEPTH]; + YYSTYPE *yyvs = yyvsa; + YYSTYPE *yyvsp; + + + #define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) + YYSIZE_T yystacksize = YYINITDEPTH; + + /* The variables used to return semantic value and location from the + action routines. */ + YYSTYPE yyval; + + /* The number of symbols on the RHS of the reduced rule. Keep to zero when no symbol should be popped. */ int yylen = 0; - yytoken = 0; - yyss = yyssa; - yyvs = yyvsa; - yystacksize = YYINITDEPTH; - YYDPRINTF ((stderr, "Starting parse\n")); yystate = 0; yyerrstatus = 0; yynerrs = 0; - yychar = YYEMPTY; /* Cause a token to be read. */ + yychar = YYEMPTY; /* Cause a token to be read. */ /* Initialize stack pointers. Waste one element of value and location stack so that they stay on the same level as the state stack. The wasted elements are never initialized. */ + yyssp = yyss; yyvsp = yyvs; @@ -2235,6 +2208,7 @@ yyparse () YYSTYPE *yyvs1 = yyvs; yytype_int16 *yyss1 = yyss; + /* Each stack pointer address is followed by the size of the data in use in that stack, in bytes. This used to be a conditional around just the two extra args, but that might @@ -2242,6 +2216,7 @@ yyparse () yyoverflow (YY_("memory exhausted"), &yyss1, yysize * sizeof (*yyssp), &yyvs1, yysize * sizeof (*yyvsp), + &yystacksize); yyss = yyss1; @@ -2264,8 +2239,9 @@ yyparse () (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); if (! yyptr) goto yyexhaustedlab; - YYSTACK_RELOCATE (yyss_alloc, yyss); - YYSTACK_RELOCATE (yyvs_alloc, yyvs); + YYSTACK_RELOCATE (yyss); + YYSTACK_RELOCATE (yyvs); + # undef YYSTACK_RELOCATE if (yyss1 != yyssa) YYSTACK_FREE (yyss1); @@ -2276,6 +2252,7 @@ yyparse () yyssp = yyss + yysize - 1; yyvsp = yyvs + yysize - 1; + YYDPRINTF ((stderr, "Stack size increased to %lu\n", (unsigned long int) yystacksize)); @@ -2285,9 +2262,6 @@ yyparse () YYDPRINTF ((stderr, "Entering state %d\n", yystate)); - if (yystate == YYFINAL) - YYACCEPT; - goto yybackup; /*-----------. @@ -2296,16 +2270,16 @@ yyparse () yybackup: /* Do appropriate processing given the current state. Read a - lookahead token if we need one and don't already have one. */ + look-ahead token if we need one and don't already have one. */ - /* First try to decide what to do without reference to lookahead token. */ + /* First try to decide what to do without reference to look-ahead token. */ yyn = yypact[yystate]; - if (yypact_value_is_default (yyn)) + if (yyn == YYPACT_NINF) goto yydefault; - /* Not known => get a lookahead token if don't already have one. */ + /* Not known => get a look-ahead token if don't already have one. */ - /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ + /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */ if (yychar == YYEMPTY) { YYDPRINTF ((stderr, "Reading a token: ")); @@ -2331,22 +2305,26 @@ yybackup: yyn = yytable[yyn]; if (yyn <= 0) { - if (yytable_value_is_error (yyn)) - goto yyerrlab; + if (yyn == 0 || yyn == YYTABLE_NINF) + goto yyerrlab; yyn = -yyn; goto yyreduce; } + if (yyn == YYFINAL) + YYACCEPT; + /* Count tokens shifted since error; after three, turn off error status. */ if (yyerrstatus) yyerrstatus--; - /* Shift the lookahead token. */ + /* Shift the look-ahead token. */ YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); - /* Discard the shifted token. */ - yychar = YYEMPTY; + /* Discard the shifted token unless it is eof. */ + if (yychar != YYEOF) + yychar = YYEMPTY; yystate = yyn; *++yyvsp = yylval; @@ -2386,8 +2364,6 @@ yyreduce: switch (yyn) { case 2: - -/* Line 1806 of yacc.c */ #line 128 "go.y" { xtop = concat(xtop, (yyvsp[(4) - (4)].list)); @@ -2395,8 +2371,6 @@ yyreduce: break; case 3: - -/* Line 1806 of yacc.c */ #line 134 "go.y" { prevlineno = lineno; @@ -2407,8 +2381,6 @@ yyreduce: break; case 4: - -/* Line 1806 of yacc.c */ #line 141 "go.y" { mkpackage((yyvsp[(2) - (3)].sym)->name); @@ -2416,8 +2388,6 @@ yyreduce: break; case 5: - -/* Line 1806 of yacc.c */ #line 151 "go.y" { importpkg = runtimepkg; @@ -2431,8 +2401,6 @@ yyreduce: break; case 6: - -/* Line 1806 of yacc.c */ #line 162 "go.y" { importpkg = nil; @@ -2440,8 +2408,6 @@ yyreduce: break; case 12: - -/* Line 1806 of yacc.c */ #line 176 "go.y" { Pkg *ipkg; @@ -2478,8 +2444,6 @@ yyreduce: break; case 13: - -/* Line 1806 of yacc.c */ #line 209 "go.y" { // When an invalid import path is passed to importfile, @@ -2492,8 +2456,6 @@ yyreduce: break; case 16: - -/* Line 1806 of yacc.c */ #line 224 "go.y" { // import with original name @@ -2504,8 +2466,6 @@ yyreduce: break; case 17: - -/* Line 1806 of yacc.c */ #line 231 "go.y" { // import with given name @@ -2516,8 +2476,6 @@ yyreduce: break; case 18: - -/* Line 1806 of yacc.c */ #line 238 "go.y" { // import into my name space @@ -2528,8 +2486,6 @@ yyreduce: break; case 19: - -/* Line 1806 of yacc.c */ #line 247 "go.y" { if(importpkg->name == nil) { @@ -2545,8 +2501,6 @@ yyreduce: break; case 21: - -/* Line 1806 of yacc.c */ #line 261 "go.y" { if(strcmp((yyvsp[(1) - (1)].sym)->name, "safe") == 0) @@ -2555,8 +2509,6 @@ yyreduce: break; case 22: - -/* Line 1806 of yacc.c */ #line 267 "go.y" { defercheckwidth(); @@ -2564,8 +2516,6 @@ yyreduce: break; case 23: - -/* Line 1806 of yacc.c */ #line 271 "go.y" { resumecheckwidth(); @@ -2574,8 +2524,6 @@ yyreduce: break; case 24: - -/* Line 1806 of yacc.c */ #line 280 "go.y" { yyerror("empty top-level declaration"); @@ -2584,8 +2532,6 @@ yyreduce: break; case 26: - -/* Line 1806 of yacc.c */ #line 286 "go.y" { (yyval.list) = list1((yyvsp[(1) - (1)].node)); @@ -2593,8 +2539,6 @@ yyreduce: break; case 27: - -/* Line 1806 of yacc.c */ #line 290 "go.y" { yyerror("non-declaration statement outside function body"); @@ -2603,8 +2547,6 @@ yyreduce: break; case 28: - -/* Line 1806 of yacc.c */ #line 295 "go.y" { (yyval.list) = nil; @@ -2612,8 +2554,6 @@ yyreduce: break; case 29: - -/* Line 1806 of yacc.c */ #line 301 "go.y" { (yyval.list) = (yyvsp[(2) - (2)].list); @@ -2621,8 +2561,6 @@ yyreduce: break; case 30: - -/* Line 1806 of yacc.c */ #line 305 "go.y" { (yyval.list) = (yyvsp[(3) - (5)].list); @@ -2630,8 +2568,6 @@ yyreduce: break; case 31: - -/* Line 1806 of yacc.c */ #line 309 "go.y" { (yyval.list) = nil; @@ -2639,8 +2575,6 @@ yyreduce: break; case 32: - -/* Line 1806 of yacc.c */ #line 313 "go.y" { (yyval.list) = (yyvsp[(2) - (2)].list); @@ -2650,8 +2584,6 @@ yyreduce: break; case 33: - -/* Line 1806 of yacc.c */ #line 319 "go.y" { (yyval.list) = (yyvsp[(3) - (5)].list); @@ -2661,8 +2593,6 @@ yyreduce: break; case 34: - -/* Line 1806 of yacc.c */ #line 325 "go.y" { (yyval.list) = concat((yyvsp[(3) - (7)].list), (yyvsp[(5) - (7)].list)); @@ -2672,8 +2602,6 @@ yyreduce: break; case 35: - -/* Line 1806 of yacc.c */ #line 331 "go.y" { (yyval.list) = nil; @@ -2682,8 +2610,6 @@ yyreduce: break; case 36: - -/* Line 1806 of yacc.c */ #line 336 "go.y" { (yyval.list) = list1((yyvsp[(2) - (2)].node)); @@ -2691,8 +2617,6 @@ yyreduce: break; case 37: - -/* Line 1806 of yacc.c */ #line 340 "go.y" { (yyval.list) = (yyvsp[(3) - (5)].list); @@ -2700,8 +2624,6 @@ yyreduce: break; case 38: - -/* Line 1806 of yacc.c */ #line 344 "go.y" { (yyval.list) = nil; @@ -2709,8 +2631,6 @@ yyreduce: break; case 39: - -/* Line 1806 of yacc.c */ #line 350 "go.y" { iota = 0; @@ -2718,8 +2638,6 @@ yyreduce: break; case 40: - -/* Line 1806 of yacc.c */ #line 356 "go.y" { (yyval.list) = variter((yyvsp[(1) - (2)].list), (yyvsp[(2) - (2)].node), nil); @@ -2727,8 +2645,6 @@ yyreduce: break; case 41: - -/* Line 1806 of yacc.c */ #line 360 "go.y" { (yyval.list) = variter((yyvsp[(1) - (4)].list), (yyvsp[(2) - (4)].node), (yyvsp[(4) - (4)].list)); @@ -2736,8 +2652,6 @@ yyreduce: break; case 42: - -/* Line 1806 of yacc.c */ #line 364 "go.y" { (yyval.list) = variter((yyvsp[(1) - (3)].list), nil, (yyvsp[(3) - (3)].list)); @@ -2745,8 +2659,6 @@ yyreduce: break; case 43: - -/* Line 1806 of yacc.c */ #line 370 "go.y" { (yyval.list) = constiter((yyvsp[(1) - (4)].list), (yyvsp[(2) - (4)].node), (yyvsp[(4) - (4)].list)); @@ -2754,8 +2666,6 @@ yyreduce: break; case 44: - -/* Line 1806 of yacc.c */ #line 374 "go.y" { (yyval.list) = constiter((yyvsp[(1) - (3)].list), N, (yyvsp[(3) - (3)].list)); @@ -2763,8 +2673,6 @@ yyreduce: break; case 46: - -/* Line 1806 of yacc.c */ #line 381 "go.y" { (yyval.list) = constiter((yyvsp[(1) - (2)].list), (yyvsp[(2) - (2)].node), nil); @@ -2772,8 +2680,6 @@ yyreduce: break; case 47: - -/* Line 1806 of yacc.c */ #line 385 "go.y" { (yyval.list) = constiter((yyvsp[(1) - (1)].list), N, nil); @@ -2781,8 +2687,6 @@ yyreduce: break; case 48: - -/* Line 1806 of yacc.c */ #line 391 "go.y" { // different from dclname because the name @@ -2793,8 +2697,6 @@ yyreduce: break; case 49: - -/* Line 1806 of yacc.c */ #line 400 "go.y" { (yyval.node) = typedcl1((yyvsp[(1) - (2)].node), (yyvsp[(2) - (2)].node), 1); @@ -2802,18 +2704,28 @@ yyreduce: break; case 50: - -/* Line 1806 of yacc.c */ #line 406 "go.y" { (yyval.node) = (yyvsp[(1) - (1)].node); + + // These nodes do not carry line numbers. + // Since a bare name used as an expression is an error, + // introduce a wrapper node to give the correct line. + switch((yyval.node)->op) { + case ONAME: + case ONONAME: + case OTYPE: + case OPACK: + case OLITERAL: + (yyval.node) = nod(OPAREN, (yyval.node), N); + (yyval.node)->implicit = 1; + break; + } } break; case 51: - -/* Line 1806 of yacc.c */ -#line 410 "go.y" +#line 424 "go.y" { (yyval.node) = nod(OASOP, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); (yyval.node)->etype = (yyvsp[(2) - (3)].i); // rathole to pass opcode @@ -2821,9 +2733,7 @@ yyreduce: break; case 52: - -/* Line 1806 of yacc.c */ -#line 415 "go.y" +#line 429 "go.y" { if((yyvsp[(1) - (3)].list)->next == nil && (yyvsp[(3) - (3)].list)->next == nil) { // simple @@ -2838,9 +2748,7 @@ yyreduce: break; case 53: - -/* Line 1806 of yacc.c */ -#line 427 "go.y" +#line 441 "go.y" { if((yyvsp[(3) - (3)].list)->n->op == OTYPESW) { (yyval.node) = nod(OTYPESW, N, (yyvsp[(3) - (3)].list)->n->right); @@ -2854,14 +2762,12 @@ yyreduce: (yyval.node)->left = dclname((yyvsp[(1) - (3)].list)->n->sym); // it's a colas, so must not re-use an oldname. break; } - (yyval.node) = colas((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].list)); + (yyval.node) = colas((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].list), (yyvsp[(2) - (3)].i)); } break; case 54: - -/* Line 1806 of yacc.c */ -#line 443 "go.y" +#line 457 "go.y" { (yyval.node) = nod(OASOP, (yyvsp[(1) - (2)].node), nodintconst(1)); (yyval.node)->etype = OADD; @@ -2869,9 +2775,7 @@ yyreduce: break; case 55: - -/* Line 1806 of yacc.c */ -#line 448 "go.y" +#line 462 "go.y" { (yyval.node) = nod(OASOP, (yyvsp[(1) - (2)].node), nodintconst(1)); (yyval.node)->etype = OSUB; @@ -2879,9 +2783,7 @@ yyreduce: break; case 56: - -/* Line 1806 of yacc.c */ -#line 455 "go.y" +#line 469 "go.y" { Node *n, *nn; @@ -2904,9 +2806,7 @@ yyreduce: break; case 57: - -/* Line 1806 of yacc.c */ -#line 475 "go.y" +#line 489 "go.y" { Node *n; @@ -2927,23 +2827,19 @@ yyreduce: break; case 58: - -/* Line 1806 of yacc.c */ -#line 493 "go.y" +#line 507 "go.y" { // will be converted to OCASE // right will point to next case // done in casebody() markdcl(); (yyval.node) = nod(OXCASE, N, N); - (yyval.node)->list = list1(colas((yyvsp[(2) - (5)].list), list1((yyvsp[(4) - (5)].node)))); + (yyval.node)->list = list1(colas((yyvsp[(2) - (5)].list), list1((yyvsp[(4) - (5)].node)), (yyvsp[(3) - (5)].i))); } break; case 59: - -/* Line 1806 of yacc.c */ -#line 502 "go.y" +#line 516 "go.y" { Node *n, *nn; @@ -2962,18 +2858,14 @@ yyreduce: break; case 60: - -/* Line 1806 of yacc.c */ -#line 520 "go.y" +#line 534 "go.y" { markdcl(); } break; case 61: - -/* Line 1806 of yacc.c */ -#line 524 "go.y" +#line 538 "go.y" { (yyval.node) = liststmt((yyvsp[(3) - (4)].list)); popdcl(); @@ -2981,9 +2873,7 @@ yyreduce: break; case 62: - -/* Line 1806 of yacc.c */ -#line 531 "go.y" +#line 545 "go.y" { // If the last token read by the lexer was consumed // as part of the case, clear it (parser has cleared yychar). @@ -2996,9 +2886,7 @@ yyreduce: break; case 63: - -/* Line 1806 of yacc.c */ -#line 541 "go.y" +#line 555 "go.y" { int last; @@ -3020,36 +2908,28 @@ yyreduce: break; case 64: - -/* Line 1806 of yacc.c */ -#line 561 "go.y" +#line 575 "go.y" { (yyval.list) = nil; } break; case 65: - -/* Line 1806 of yacc.c */ -#line 565 "go.y" +#line 579 "go.y" { (yyval.list) = list((yyvsp[(1) - (2)].list), (yyvsp[(2) - (2)].node)); } break; case 66: - -/* Line 1806 of yacc.c */ -#line 571 "go.y" +#line 585 "go.y" { markdcl(); } break; case 67: - -/* Line 1806 of yacc.c */ -#line 575 "go.y" +#line 589 "go.y" { (yyval.list) = (yyvsp[(3) - (4)].list); popdcl(); @@ -3057,9 +2937,7 @@ yyreduce: break; case 68: - -/* Line 1806 of yacc.c */ -#line 582 "go.y" +#line 596 "go.y" { (yyval.node) = nod(ORANGE, N, (yyvsp[(4) - (4)].node)); (yyval.node)->list = (yyvsp[(1) - (4)].list); @@ -3068,9 +2946,7 @@ yyreduce: break; case 69: - -/* Line 1806 of yacc.c */ -#line 588 "go.y" +#line 602 "go.y" { (yyval.node) = nod(ORANGE, N, (yyvsp[(4) - (4)].node)); (yyval.node)->list = (yyvsp[(1) - (4)].list); @@ -3080,9 +2956,7 @@ yyreduce: break; case 70: - -/* Line 1806 of yacc.c */ -#line 597 "go.y" +#line 611 "go.y" { // init ; test ; incr if((yyvsp[(5) - (5)].node) != N && (yyvsp[(5) - (5)].node)->colas != 0) @@ -3096,9 +2970,7 @@ yyreduce: break; case 71: - -/* Line 1806 of yacc.c */ -#line 608 "go.y" +#line 622 "go.y" { // normal test (yyval.node) = nod(OFOR, N, N); @@ -3107,9 +2979,7 @@ yyreduce: break; case 73: - -/* Line 1806 of yacc.c */ -#line 617 "go.y" +#line 631 "go.y" { (yyval.node) = (yyvsp[(1) - (2)].node); (yyval.node)->nbody = concat((yyval.node)->nbody, (yyvsp[(2) - (2)].list)); @@ -3117,18 +2987,14 @@ yyreduce: break; case 74: - -/* Line 1806 of yacc.c */ -#line 624 "go.y" +#line 638 "go.y" { markdcl(); } break; case 75: - -/* Line 1806 of yacc.c */ -#line 628 "go.y" +#line 642 "go.y" { (yyval.node) = (yyvsp[(3) - (3)].node); popdcl(); @@ -3136,9 +3002,7 @@ yyreduce: break; case 76: - -/* Line 1806 of yacc.c */ -#line 635 "go.y" +#line 649 "go.y" { // test (yyval.node) = nod(OIF, N, N); @@ -3147,9 +3011,7 @@ yyreduce: break; case 77: - -/* Line 1806 of yacc.c */ -#line 641 "go.y" +#line 655 "go.y" { // init ; test (yyval.node) = nod(OIF, N, N); @@ -3160,18 +3022,14 @@ yyreduce: break; case 78: - -/* Line 1806 of yacc.c */ -#line 652 "go.y" +#line 666 "go.y" { markdcl(); } break; case 79: - -/* Line 1806 of yacc.c */ -#line 656 "go.y" +#line 670 "go.y" { if((yyvsp[(3) - (3)].node)->ntest == N) yyerror("missing condition in if statement"); @@ -3179,66 +3037,89 @@ yyreduce: break; case 80: - -/* Line 1806 of yacc.c */ -#line 661 "go.y" +#line 675 "go.y" { (yyvsp[(3) - (5)].node)->nbody = (yyvsp[(5) - (5)].list); } break; case 81: - -/* Line 1806 of yacc.c */ -#line 665 "go.y" +#line 679 "go.y" { + Node *n; + NodeList *nn; + + (yyval.node) = (yyvsp[(3) - (8)].node); + n = (yyvsp[(3) - (8)].node); popdcl(); - (yyval.node) = (yyvsp[(3) - (7)].node); - if((yyvsp[(7) - (7)].node) != N) - (yyval.node)->nelse = list1((yyvsp[(7) - (7)].node)); + for(nn = concat((yyvsp[(7) - (8)].list), (yyvsp[(8) - (8)].list)); nn; nn = nn->next) { + if(nn->n->op == OIF) + popdcl(); + n->nelse = list1(nn->n); + n = nn->n; + } } break; case 82: - -/* Line 1806 of yacc.c */ -#line 673 "go.y" +#line 696 "go.y" { - (yyval.node) = N; + markdcl(); } break; case 83: - -/* Line 1806 of yacc.c */ -#line 677 "go.y" +#line 700 "go.y" { - (yyval.node) = (yyvsp[(2) - (2)].node); + if((yyvsp[(4) - (5)].node)->ntest == N) + yyerror("missing condition in if statement"); + (yyvsp[(4) - (5)].node)->nbody = (yyvsp[(5) - (5)].list); + (yyval.list) = list1((yyvsp[(4) - (5)].node)); } break; case 84: - -/* Line 1806 of yacc.c */ -#line 681 "go.y" +#line 708 "go.y" { - (yyval.node) = (yyvsp[(2) - (2)].node); + (yyval.list) = nil; } break; case 85: - -/* Line 1806 of yacc.c */ -#line 687 "go.y" +#line 712 "go.y" { - markdcl(); + (yyval.list) = concat((yyvsp[(1) - (2)].list), (yyvsp[(2) - (2)].list)); } break; case 86: +#line 717 "go.y" + { + (yyval.list) = nil; + } + break; + + case 87: +#line 721 "go.y" + { + NodeList *node; + + node = mal(sizeof *node); + node->n = (yyvsp[(2) - (2)].node); + node->end = node; + (yyval.list) = node; + } + break; + + case 88: +#line 732 "go.y" + { + markdcl(); + } + break; -/* Line 1806 of yacc.c */ -#line 691 "go.y" + case 89: +#line 736 "go.y" { Node *n; n = (yyvsp[(3) - (3)].node)->ntest; @@ -3248,10 +3129,8 @@ yyreduce: } break; - case 87: - -/* Line 1806 of yacc.c */ -#line 699 "go.y" + case 90: +#line 744 "go.y" { (yyval.node) = (yyvsp[(3) - (7)].node); (yyval.node)->op = OSWITCH; @@ -3261,19 +3140,15 @@ yyreduce: } break; - case 88: - -/* Line 1806 of yacc.c */ -#line 709 "go.y" + case 91: +#line 754 "go.y" { typesw = nod(OXXX, typesw, N); } break; - case 89: - -/* Line 1806 of yacc.c */ -#line 713 "go.y" + case 92: +#line 758 "go.y" { (yyval.node) = nod(OSELECT, N, N); (yyval.node)->lineno = typesw->lineno; @@ -3282,199 +3157,155 @@ yyreduce: } break; - case 91: - -/* Line 1806 of yacc.c */ -#line 726 "go.y" + case 94: +#line 771 "go.y" { (yyval.node) = nod(OOROR, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); } break; - case 92: - -/* Line 1806 of yacc.c */ -#line 730 "go.y" + case 95: +#line 775 "go.y" { (yyval.node) = nod(OANDAND, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); } break; - case 93: - -/* Line 1806 of yacc.c */ -#line 734 "go.y" + case 96: +#line 779 "go.y" { (yyval.node) = nod(OEQ, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); } break; - case 94: - -/* Line 1806 of yacc.c */ -#line 738 "go.y" + case 97: +#line 783 "go.y" { (yyval.node) = nod(ONE, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); } break; - case 95: - -/* Line 1806 of yacc.c */ -#line 742 "go.y" + case 98: +#line 787 "go.y" { (yyval.node) = nod(OLT, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); } break; - case 96: - -/* Line 1806 of yacc.c */ -#line 746 "go.y" + case 99: +#line 791 "go.y" { (yyval.node) = nod(OLE, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); } break; - case 97: - -/* Line 1806 of yacc.c */ -#line 750 "go.y" + case 100: +#line 795 "go.y" { (yyval.node) = nod(OGE, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); } break; - case 98: - -/* Line 1806 of yacc.c */ -#line 754 "go.y" + case 101: +#line 799 "go.y" { (yyval.node) = nod(OGT, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); } break; - case 99: - -/* Line 1806 of yacc.c */ -#line 758 "go.y" + case 102: +#line 803 "go.y" { (yyval.node) = nod(OADD, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); } break; - case 100: - -/* Line 1806 of yacc.c */ -#line 762 "go.y" + case 103: +#line 807 "go.y" { (yyval.node) = nod(OSUB, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); } break; - case 101: - -/* Line 1806 of yacc.c */ -#line 766 "go.y" + case 104: +#line 811 "go.y" { (yyval.node) = nod(OOR, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); } break; - case 102: - -/* Line 1806 of yacc.c */ -#line 770 "go.y" + case 105: +#line 815 "go.y" { (yyval.node) = nod(OXOR, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); } break; - case 103: - -/* Line 1806 of yacc.c */ -#line 774 "go.y" + case 106: +#line 819 "go.y" { (yyval.node) = nod(OMUL, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); } break; - case 104: - -/* Line 1806 of yacc.c */ -#line 778 "go.y" + case 107: +#line 823 "go.y" { (yyval.node) = nod(ODIV, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); } break; - case 105: - -/* Line 1806 of yacc.c */ -#line 782 "go.y" + case 108: +#line 827 "go.y" { (yyval.node) = nod(OMOD, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); } break; - case 106: - -/* Line 1806 of yacc.c */ -#line 786 "go.y" + case 109: +#line 831 "go.y" { (yyval.node) = nod(OAND, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); } break; - case 107: - -/* Line 1806 of yacc.c */ -#line 790 "go.y" + case 110: +#line 835 "go.y" { (yyval.node) = nod(OANDNOT, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); } break; - case 108: - -/* Line 1806 of yacc.c */ -#line 794 "go.y" + case 111: +#line 839 "go.y" { (yyval.node) = nod(OLSH, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); } break; - case 109: - -/* Line 1806 of yacc.c */ -#line 798 "go.y" + case 112: +#line 843 "go.y" { (yyval.node) = nod(ORSH, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); } break; - case 110: - -/* Line 1806 of yacc.c */ -#line 803 "go.y" + case 113: +#line 848 "go.y" { (yyval.node) = nod(OSEND, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); } break; - case 112: - -/* Line 1806 of yacc.c */ -#line 810 "go.y" + case 115: +#line 855 "go.y" { (yyval.node) = nod(OIND, (yyvsp[(2) - (2)].node), N); } break; - case 113: - -/* Line 1806 of yacc.c */ -#line 814 "go.y" + case 116: +#line 859 "go.y" { if((yyvsp[(2) - (2)].node)->op == OCOMPLIT) { // Special case for &T{...}: turn into (*T){...}. @@ -3487,84 +3318,66 @@ yyreduce: } break; - case 114: - -/* Line 1806 of yacc.c */ -#line 825 "go.y" + case 117: +#line 870 "go.y" { (yyval.node) = nod(OPLUS, (yyvsp[(2) - (2)].node), N); } break; - case 115: - -/* Line 1806 of yacc.c */ -#line 829 "go.y" + case 118: +#line 874 "go.y" { (yyval.node) = nod(OMINUS, (yyvsp[(2) - (2)].node), N); } break; - case 116: - -/* Line 1806 of yacc.c */ -#line 833 "go.y" + case 119: +#line 878 "go.y" { (yyval.node) = nod(ONOT, (yyvsp[(2) - (2)].node), N); } break; - case 117: - -/* Line 1806 of yacc.c */ -#line 837 "go.y" + case 120: +#line 882 "go.y" { yyerror("the bitwise complement operator is ^"); (yyval.node) = nod(OCOM, (yyvsp[(2) - (2)].node), N); } break; - case 118: - -/* Line 1806 of yacc.c */ -#line 842 "go.y" + case 121: +#line 887 "go.y" { (yyval.node) = nod(OCOM, (yyvsp[(2) - (2)].node), N); } break; - case 119: - -/* Line 1806 of yacc.c */ -#line 846 "go.y" + case 122: +#line 891 "go.y" { (yyval.node) = nod(ORECV, (yyvsp[(2) - (2)].node), N); } break; - case 120: - -/* Line 1806 of yacc.c */ -#line 856 "go.y" + case 123: +#line 901 "go.y" { (yyval.node) = nod(OCALL, (yyvsp[(1) - (3)].node), N); } break; - case 121: - -/* Line 1806 of yacc.c */ -#line 860 "go.y" + case 124: +#line 905 "go.y" { (yyval.node) = nod(OCALL, (yyvsp[(1) - (5)].node), N); (yyval.node)->list = (yyvsp[(3) - (5)].list); } break; - case 122: - -/* Line 1806 of yacc.c */ -#line 865 "go.y" + case 125: +#line 910 "go.y" { (yyval.node) = nod(OCALL, (yyvsp[(1) - (6)].node), N); (yyval.node)->list = (yyvsp[(3) - (6)].list); @@ -3572,19 +3385,15 @@ yyreduce: } break; - case 123: - -/* Line 1806 of yacc.c */ -#line 873 "go.y" + case 126: +#line 918 "go.y" { (yyval.node) = nodlit((yyvsp[(1) - (1)].val)); } break; - case 125: - -/* Line 1806 of yacc.c */ -#line 878 "go.y" + case 128: +#line 923 "go.y" { if((yyvsp[(1) - (3)].node)->op == OPACK) { Sym *s; @@ -3597,57 +3406,45 @@ yyreduce: } break; - case 126: - -/* Line 1806 of yacc.c */ -#line 889 "go.y" + case 129: +#line 934 "go.y" { (yyval.node) = nod(ODOTTYPE, (yyvsp[(1) - (5)].node), (yyvsp[(4) - (5)].node)); } break; - case 127: - -/* Line 1806 of yacc.c */ -#line 893 "go.y" + case 130: +#line 938 "go.y" { (yyval.node) = nod(OTYPESW, N, (yyvsp[(1) - (5)].node)); } break; - case 128: - -/* Line 1806 of yacc.c */ -#line 897 "go.y" + case 131: +#line 942 "go.y" { (yyval.node) = nod(OINDEX, (yyvsp[(1) - (4)].node), (yyvsp[(3) - (4)].node)); } break; - case 129: - -/* Line 1806 of yacc.c */ -#line 901 "go.y" + case 132: +#line 946 "go.y" { (yyval.node) = nod(OSLICE, (yyvsp[(1) - (6)].node), nod(OKEY, (yyvsp[(3) - (6)].node), (yyvsp[(5) - (6)].node))); } break; - case 131: - -/* Line 1806 of yacc.c */ -#line 906 "go.y" + case 134: +#line 951 "go.y" { // conversion - (yyval.node) = nod(OCALL, (yyvsp[(1) - (4)].node), N); - (yyval.node)->list = list1((yyvsp[(3) - (4)].node)); + (yyval.node) = nod(OCALL, (yyvsp[(1) - (5)].node), N); + (yyval.node)->list = list1((yyvsp[(3) - (5)].node)); } break; - case 132: - -/* Line 1806 of yacc.c */ -#line 912 "go.y" + case 135: +#line 957 "go.y" { (yyval.node) = (yyvsp[(3) - (5)].node); (yyval.node)->right = (yyvsp[(1) - (5)].node); @@ -3656,10 +3453,8 @@ yyreduce: } break; - case 133: - -/* Line 1806 of yacc.c */ -#line 919 "go.y" + case 136: +#line 964 "go.y" { (yyval.node) = (yyvsp[(3) - (5)].node); (yyval.node)->right = (yyvsp[(1) - (5)].node); @@ -3667,10 +3462,8 @@ yyreduce: } break; - case 134: - -/* Line 1806 of yacc.c */ -#line 925 "go.y" + case 137: +#line 970 "go.y" { yyerror("cannot parenthesize type in composite literal"); (yyval.node) = (yyvsp[(5) - (7)].node); @@ -3679,10 +3472,8 @@ yyreduce: } break; - case 136: - -/* Line 1806 of yacc.c */ -#line 934 "go.y" + case 139: +#line 979 "go.y" { // composite expression. // make node early so we get the right line number. @@ -3690,29 +3481,51 @@ yyreduce: } break; - case 137: - -/* Line 1806 of yacc.c */ -#line 942 "go.y" + case 140: +#line 987 "go.y" { (yyval.node) = nod(OKEY, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); } break; - case 139: + case 141: +#line 993 "go.y" + { + // These nodes do not carry line numbers. + // Since a composite literal commonly spans several lines, + // the line number on errors may be misleading. + // Introduce a wrapper node to give the correct line. + (yyval.node) = (yyvsp[(1) - (1)].node); + switch((yyval.node)->op) { + case ONAME: + case ONONAME: + case OTYPE: + case OPACK: + case OLITERAL: + (yyval.node) = nod(OPAREN, (yyval.node), N); + (yyval.node)->implicit = 1; + } + } + break; -/* Line 1806 of yacc.c */ -#line 949 "go.y" + case 142: +#line 1010 "go.y" { (yyval.node) = (yyvsp[(2) - (4)].node); (yyval.node)->list = (yyvsp[(3) - (4)].list); } break; - case 141: + case 144: +#line 1018 "go.y" + { + (yyval.node) = (yyvsp[(2) - (4)].node); + (yyval.node)->list = (yyvsp[(3) - (4)].list); + } + break; -/* Line 1806 of yacc.c */ -#line 957 "go.y" + case 146: +#line 1026 "go.y" { (yyval.node) = (yyvsp[(2) - (3)].node); @@ -3725,33 +3538,28 @@ yyreduce: case OPACK: case OTYPE: case OLITERAL: + case OTYPESW: (yyval.node) = nod(OPAREN, (yyval.node), N); } } break; - case 145: - -/* Line 1806 of yacc.c */ -#line 982 "go.y" + case 150: +#line 1052 "go.y" { (yyval.i) = LBODY; } break; - case 146: - -/* Line 1806 of yacc.c */ -#line 986 "go.y" + case 151: +#line 1056 "go.y" { (yyval.i) = '{'; } break; - case 147: - -/* Line 1806 of yacc.c */ -#line 997 "go.y" + case 152: +#line 1067 "go.y" { if((yyvsp[(1) - (1)].sym) == S) (yyval.node) = N; @@ -3760,28 +3568,22 @@ yyreduce: } break; - case 148: - -/* Line 1806 of yacc.c */ -#line 1006 "go.y" + case 153: +#line 1076 "go.y" { (yyval.node) = dclname((yyvsp[(1) - (1)].sym)); } break; - case 149: - -/* Line 1806 of yacc.c */ -#line 1011 "go.y" + case 154: +#line 1081 "go.y" { (yyval.node) = N; } break; - case 151: - -/* Line 1806 of yacc.c */ -#line 1018 "go.y" + case 156: +#line 1088 "go.y" { (yyval.sym) = (yyvsp[(1) - (1)].sym); // during imports, unqualified non-exported identifiers are from builtinpkg @@ -3790,31 +3592,31 @@ yyreduce: } break; - case 153: - -/* Line 1806 of yacc.c */ -#line 1026 "go.y" + case 158: +#line 1096 "go.y" { (yyval.sym) = S; } break; - case 154: - -/* Line 1806 of yacc.c */ -#line 1032 "go.y" + case 159: +#line 1102 "go.y" { + Pkg *p; + if((yyvsp[(2) - (4)].val).u.sval->len == 0) - (yyval.sym) = pkglookup((yyvsp[(4) - (4)].sym)->name, importpkg); - else - (yyval.sym) = pkglookup((yyvsp[(4) - (4)].sym)->name, mkpkg((yyvsp[(2) - (4)].val).u.sval)); + p = importpkg; + else { + if(isbadimport((yyvsp[(2) - (4)].val).u.sval)) + errorexit(); + p = mkpkg((yyvsp[(2) - (4)].val).u.sval); + } + (yyval.sym) = pkglookup((yyvsp[(4) - (4)].sym)->name, p); } break; - case 155: - -/* Line 1806 of yacc.c */ -#line 1041 "go.y" + case 160: +#line 1117 "go.y" { (yyval.node) = oldname((yyvsp[(1) - (1)].sym)); if((yyval.node)->pack != N) @@ -3822,56 +3624,44 @@ yyreduce: } break; - case 157: - -/* Line 1806 of yacc.c */ -#line 1061 "go.y" + case 162: +#line 1137 "go.y" { yyerror("final argument in variadic function missing type"); (yyval.node) = nod(ODDD, typenod(typ(TINTER)), N); } break; - case 158: - -/* Line 1806 of yacc.c */ -#line 1066 "go.y" + case 163: +#line 1142 "go.y" { (yyval.node) = nod(ODDD, (yyvsp[(2) - (2)].node), N); } break; - case 164: - -/* Line 1806 of yacc.c */ -#line 1077 "go.y" + case 169: +#line 1153 "go.y" { (yyval.node) = nod(OTPAREN, (yyvsp[(2) - (3)].node), N); } break; - case 168: - -/* Line 1806 of yacc.c */ -#line 1086 "go.y" + case 173: +#line 1162 "go.y" { (yyval.node) = nod(OIND, (yyvsp[(2) - (2)].node), N); } break; - case 173: - -/* Line 1806 of yacc.c */ -#line 1096 "go.y" + case 178: +#line 1172 "go.y" { (yyval.node) = nod(OTPAREN, (yyvsp[(2) - (3)].node), N); } break; - case 183: - -/* Line 1806 of yacc.c */ -#line 1117 "go.y" + case 188: +#line 1193 "go.y" { if((yyvsp[(1) - (3)].node)->op == OPACK) { Sym *s; @@ -3884,77 +3674,61 @@ yyreduce: } break; - case 184: - -/* Line 1806 of yacc.c */ -#line 1130 "go.y" + case 189: +#line 1206 "go.y" { (yyval.node) = nod(OTARRAY, (yyvsp[(2) - (4)].node), (yyvsp[(4) - (4)].node)); } break; - case 185: - -/* Line 1806 of yacc.c */ -#line 1134 "go.y" + case 190: +#line 1210 "go.y" { // array literal of nelem (yyval.node) = nod(OTARRAY, nod(ODDD, N, N), (yyvsp[(4) - (4)].node)); } break; - case 186: - -/* Line 1806 of yacc.c */ -#line 1139 "go.y" + case 191: +#line 1215 "go.y" { (yyval.node) = nod(OTCHAN, (yyvsp[(2) - (2)].node), N); (yyval.node)->etype = Cboth; } break; - case 187: - -/* Line 1806 of yacc.c */ -#line 1144 "go.y" + case 192: +#line 1220 "go.y" { (yyval.node) = nod(OTCHAN, (yyvsp[(3) - (3)].node), N); (yyval.node)->etype = Csend; } break; - case 188: - -/* Line 1806 of yacc.c */ -#line 1149 "go.y" + case 193: +#line 1225 "go.y" { (yyval.node) = nod(OTMAP, (yyvsp[(3) - (5)].node), (yyvsp[(5) - (5)].node)); } break; - case 191: - -/* Line 1806 of yacc.c */ -#line 1157 "go.y" + case 196: +#line 1233 "go.y" { (yyval.node) = nod(OIND, (yyvsp[(2) - (2)].node), N); } break; - case 192: - -/* Line 1806 of yacc.c */ -#line 1163 "go.y" + case 197: +#line 1239 "go.y" { (yyval.node) = nod(OTCHAN, (yyvsp[(3) - (3)].node), N); (yyval.node)->etype = Crecv; } break; - case 193: - -/* Line 1806 of yacc.c */ -#line 1170 "go.y" + case 198: +#line 1246 "go.y" { (yyval.node) = nod(OTSTRUCT, N, N); (yyval.node)->list = (yyvsp[(3) - (5)].list); @@ -3962,20 +3736,16 @@ yyreduce: } break; - case 194: - -/* Line 1806 of yacc.c */ -#line 1176 "go.y" + case 199: +#line 1252 "go.y" { (yyval.node) = nod(OTSTRUCT, N, N); fixlbrace((yyvsp[(2) - (3)].i)); } break; - case 195: - -/* Line 1806 of yacc.c */ -#line 1183 "go.y" + case 200: +#line 1259 "go.y" { (yyval.node) = nod(OTINTER, N, N); (yyval.node)->list = (yyvsp[(3) - (5)].list); @@ -3983,34 +3753,31 @@ yyreduce: } break; - case 196: - -/* Line 1806 of yacc.c */ -#line 1189 "go.y" + case 201: +#line 1265 "go.y" { (yyval.node) = nod(OTINTER, N, N); fixlbrace((yyvsp[(2) - (3)].i)); } break; - case 197: - -/* Line 1806 of yacc.c */ -#line 1200 "go.y" + case 202: +#line 1276 "go.y" { (yyval.node) = (yyvsp[(2) - (3)].node); if((yyval.node) == N) break; + if(noescape && (yyvsp[(3) - (3)].list) != nil) + yyerror("can only use //go:noescape with external func implementations"); (yyval.node)->nbody = (yyvsp[(3) - (3)].list); (yyval.node)->endlineno = lineno; + (yyval.node)->noescape = noescape; funcbody((yyval.node)); } break; - case 198: - -/* Line 1806 of yacc.c */ -#line 1211 "go.y" + case 203: +#line 1290 "go.y" { Node *t; @@ -4041,10 +3808,8 @@ yyreduce: } break; - case 199: - -/* Line 1806 of yacc.c */ -#line 1240 "go.y" + case 204: +#line 1319 "go.y" { Node *rcvr, *t; @@ -4077,16 +3842,15 @@ yyreduce: (yyval.node)->nname = methodname1((yyval.node)->shortname, rcvr->right); (yyval.node)->nname->defn = (yyval.node); (yyval.node)->nname->ntype = t; + (yyval.node)->nname->nointerface = nointerface; declare((yyval.node)->nname, PFUNC); funchdr((yyval.node)); } break; - case 200: - -/* Line 1806 of yacc.c */ -#line 1279 "go.y" + case 205: +#line 1359 "go.y" { Sym *s; Type *t; @@ -4098,8 +3862,10 @@ yyreduce: importsym(s, ONAME); if(s->def != N && s->def->op == ONAME) { - if(eqtype(t, s->def->type)) + if(eqtype(t, s->def->type)) { + dclcontext = PDISCARD; // since we skip funchdr below break; + } yyerror("inconsistent definition for func %S during import\n\t%T\n\t%T", s, s->def->type, t); } @@ -4111,16 +3877,15 @@ yyreduce: } break; - case 201: - -/* Line 1806 of yacc.c */ -#line 1302 "go.y" + case 206: +#line 1384 "go.y" { (yyval.node) = methodname1(newname((yyvsp[(4) - (8)].sym)), (yyvsp[(2) - (8)].list)->n->right); (yyval.node)->type = functype((yyvsp[(2) - (8)].list)->n, (yyvsp[(6) - (8)].list), (yyvsp[(8) - (8)].list)); checkwidth((yyval.node)->type); - addmethod((yyvsp[(4) - (8)].sym), (yyval.node)->type, 0); + addmethod((yyvsp[(4) - (8)].sym), (yyval.node)->type, 0, nointerface); + nointerface = 0; funchdr((yyval.node)); // inl.c's inlnode in on a dotmeth node expects to find the inlineable body as @@ -4131,10 +3896,8 @@ yyreduce: } break; - case 202: - -/* Line 1806 of yacc.c */ -#line 1319 "go.y" + case 207: +#line 1402 "go.y" { (yyvsp[(3) - (5)].list) = checkarglist((yyvsp[(3) - (5)].list), 1); (yyval.node) = nod(OTFUNC, N, N); @@ -4143,19 +3906,15 @@ yyreduce: } break; - case 203: - -/* Line 1806 of yacc.c */ -#line 1327 "go.y" + case 208: +#line 1410 "go.y" { (yyval.list) = nil; } break; - case 204: - -/* Line 1806 of yacc.c */ -#line 1331 "go.y" + case 209: +#line 1414 "go.y" { (yyval.list) = (yyvsp[(2) - (3)].list); if((yyval.list) == nil) @@ -4163,149 +3922,119 @@ yyreduce: } break; - case 205: - -/* Line 1806 of yacc.c */ -#line 1339 "go.y" + case 210: +#line 1422 "go.y" { (yyval.list) = nil; } break; - case 206: - -/* Line 1806 of yacc.c */ -#line 1343 "go.y" + case 211: +#line 1426 "go.y" { (yyval.list) = list1(nod(ODCLFIELD, N, (yyvsp[(1) - (1)].node))); } break; - case 207: - -/* Line 1806 of yacc.c */ -#line 1347 "go.y" + case 212: +#line 1430 "go.y" { (yyvsp[(2) - (3)].list) = checkarglist((yyvsp[(2) - (3)].list), 0); (yyval.list) = (yyvsp[(2) - (3)].list); } break; - case 208: - -/* Line 1806 of yacc.c */ -#line 1354 "go.y" + case 213: +#line 1437 "go.y" { closurehdr((yyvsp[(1) - (1)].node)); } break; - case 209: - -/* Line 1806 of yacc.c */ -#line 1360 "go.y" + case 214: +#line 1443 "go.y" { (yyval.node) = closurebody((yyvsp[(3) - (4)].list)); fixlbrace((yyvsp[(2) - (4)].i)); } break; - case 210: - -/* Line 1806 of yacc.c */ -#line 1365 "go.y" + case 215: +#line 1448 "go.y" { (yyval.node) = closurebody(nil); } break; - case 211: - -/* Line 1806 of yacc.c */ -#line 1376 "go.y" + case 216: +#line 1459 "go.y" { (yyval.list) = nil; } break; - case 212: - -/* Line 1806 of yacc.c */ -#line 1380 "go.y" + case 217: +#line 1463 "go.y" { (yyval.list) = concat((yyvsp[(1) - (3)].list), (yyvsp[(2) - (3)].list)); if(nsyntaxerrors == 0) testdclstack(); + nointerface = 0; + noescape = 0; } break; - case 214: - -/* Line 1806 of yacc.c */ -#line 1389 "go.y" + case 219: +#line 1474 "go.y" { (yyval.list) = concat((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].list)); } break; - case 216: - -/* Line 1806 of yacc.c */ -#line 1396 "go.y" + case 221: +#line 1481 "go.y" { (yyval.list) = concat((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].list)); } break; - case 217: - -/* Line 1806 of yacc.c */ -#line 1402 "go.y" + case 222: +#line 1487 "go.y" { (yyval.list) = list1((yyvsp[(1) - (1)].node)); } break; - case 218: - -/* Line 1806 of yacc.c */ -#line 1406 "go.y" + case 223: +#line 1491 "go.y" { (yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node)); } break; - case 220: - -/* Line 1806 of yacc.c */ -#line 1413 "go.y" + case 225: +#line 1498 "go.y" { (yyval.list) = concat((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].list)); } break; - case 221: - -/* Line 1806 of yacc.c */ -#line 1419 "go.y" + case 226: +#line 1504 "go.y" { (yyval.list) = list1((yyvsp[(1) - (1)].node)); } break; - case 222: - -/* Line 1806 of yacc.c */ -#line 1423 "go.y" + case 227: +#line 1508 "go.y" { (yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node)); } break; - case 223: - -/* Line 1806 of yacc.c */ -#line 1429 "go.y" + case 228: +#line 1514 "go.y" { NodeList *l; @@ -4330,20 +4059,16 @@ yyreduce: } break; - case 224: - -/* Line 1806 of yacc.c */ -#line 1452 "go.y" + case 229: +#line 1537 "go.y" { (yyvsp[(1) - (2)].node)->val = (yyvsp[(2) - (2)].val); (yyval.list) = list1((yyvsp[(1) - (2)].node)); } break; - case 225: - -/* Line 1806 of yacc.c */ -#line 1457 "go.y" + case 230: +#line 1542 "go.y" { (yyvsp[(2) - (4)].node)->val = (yyvsp[(4) - (4)].val); (yyval.list) = list1((yyvsp[(2) - (4)].node)); @@ -4351,10 +4076,8 @@ yyreduce: } break; - case 226: - -/* Line 1806 of yacc.c */ -#line 1463 "go.y" + case 231: +#line 1548 "go.y" { (yyvsp[(2) - (3)].node)->right = nod(OIND, (yyvsp[(2) - (3)].node)->right, N); (yyvsp[(2) - (3)].node)->val = (yyvsp[(3) - (3)].val); @@ -4362,10 +4085,8 @@ yyreduce: } break; - case 227: - -/* Line 1806 of yacc.c */ -#line 1469 "go.y" + case 232: +#line 1554 "go.y" { (yyvsp[(3) - (5)].node)->right = nod(OIND, (yyvsp[(3) - (5)].node)->right, N); (yyvsp[(3) - (5)].node)->val = (yyvsp[(5) - (5)].val); @@ -4374,10 +4095,8 @@ yyreduce: } break; - case 228: - -/* Line 1806 of yacc.c */ -#line 1476 "go.y" + case 233: +#line 1561 "go.y" { (yyvsp[(3) - (5)].node)->right = nod(OIND, (yyvsp[(3) - (5)].node)->right, N); (yyvsp[(3) - (5)].node)->val = (yyvsp[(5) - (5)].val); @@ -4386,10 +4105,8 @@ yyreduce: } break; - case 229: - -/* Line 1806 of yacc.c */ -#line 1485 "go.y" + case 234: +#line 1570 "go.y" { Node *n; @@ -4400,10 +4117,8 @@ yyreduce: } break; - case 230: - -/* Line 1806 of yacc.c */ -#line 1494 "go.y" + case 235: +#line 1579 "go.y" { Pkg *pkg; @@ -4418,48 +4133,38 @@ yyreduce: } break; - case 231: - -/* Line 1806 of yacc.c */ -#line 1509 "go.y" + case 236: +#line 1594 "go.y" { (yyval.node) = embedded((yyvsp[(1) - (1)].sym)); } break; - case 232: - -/* Line 1806 of yacc.c */ -#line 1515 "go.y" + case 237: +#line 1600 "go.y" { (yyval.node) = nod(ODCLFIELD, (yyvsp[(1) - (2)].node), (yyvsp[(2) - (2)].node)); ifacedcl((yyval.node)); } break; - case 233: - -/* Line 1806 of yacc.c */ -#line 1520 "go.y" + case 238: +#line 1605 "go.y" { (yyval.node) = nod(ODCLFIELD, N, oldname((yyvsp[(1) - (1)].sym))); } break; - case 234: - -/* Line 1806 of yacc.c */ -#line 1524 "go.y" + case 239: +#line 1609 "go.y" { (yyval.node) = nod(ODCLFIELD, N, oldname((yyvsp[(2) - (3)].sym))); yyerror("cannot parenthesize embedded type"); } break; - case 235: - -/* Line 1806 of yacc.c */ -#line 1531 "go.y" + case 240: +#line 1616 "go.y" { // without func keyword (yyvsp[(2) - (4)].list) = checkarglist((yyvsp[(2) - (4)].list), 1); @@ -4469,10 +4174,8 @@ yyreduce: } break; - case 237: - -/* Line 1806 of yacc.c */ -#line 1545 "go.y" + case 242: +#line 1630 "go.y" { (yyval.node) = nod(ONONAME, N, N); (yyval.node)->sym = (yyvsp[(1) - (2)].sym); @@ -4480,10 +4183,8 @@ yyreduce: } break; - case 238: - -/* Line 1806 of yacc.c */ -#line 1551 "go.y" + case 243: +#line 1636 "go.y" { (yyval.node) = nod(ONONAME, N, N); (yyval.node)->sym = (yyvsp[(1) - (2)].sym); @@ -4491,83 +4192,65 @@ yyreduce: } break; - case 240: - -/* Line 1806 of yacc.c */ -#line 1560 "go.y" + case 245: +#line 1645 "go.y" { (yyval.list) = list1((yyvsp[(1) - (1)].node)); } break; - case 241: - -/* Line 1806 of yacc.c */ -#line 1564 "go.y" + case 246: +#line 1649 "go.y" { (yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node)); } break; - case 242: - -/* Line 1806 of yacc.c */ -#line 1569 "go.y" + case 247: +#line 1654 "go.y" { (yyval.list) = nil; } break; - case 243: - -/* Line 1806 of yacc.c */ -#line 1573 "go.y" + case 248: +#line 1658 "go.y" { (yyval.list) = (yyvsp[(1) - (2)].list); } break; - case 244: - -/* Line 1806 of yacc.c */ -#line 1581 "go.y" + case 249: +#line 1666 "go.y" { (yyval.node) = N; } break; - case 246: - -/* Line 1806 of yacc.c */ -#line 1586 "go.y" + case 251: +#line 1671 "go.y" { (yyval.node) = liststmt((yyvsp[(1) - (1)].list)); } break; - case 248: - -/* Line 1806 of yacc.c */ -#line 1591 "go.y" + case 253: +#line 1676 "go.y" { (yyval.node) = N; } break; - case 254: - -/* Line 1806 of yacc.c */ -#line 1602 "go.y" + case 259: +#line 1687 "go.y" { (yyvsp[(1) - (2)].node) = nod(OLABEL, (yyvsp[(1) - (2)].node), N); (yyvsp[(1) - (2)].node)->sym = dclstack; // context, for goto restrictions } break; - case 255: - -/* Line 1806 of yacc.c */ -#line 1607 "go.y" + case 260: +#line 1692 "go.y" { NodeList *l; @@ -4579,66 +4262,52 @@ yyreduce: } break; - case 256: - -/* Line 1806 of yacc.c */ -#line 1617 "go.y" + case 261: +#line 1702 "go.y" { // will be converted to OFALL (yyval.node) = nod(OXFALL, N, N); } break; - case 257: - -/* Line 1806 of yacc.c */ -#line 1622 "go.y" + case 262: +#line 1707 "go.y" { (yyval.node) = nod(OBREAK, (yyvsp[(2) - (2)].node), N); } break; - case 258: - -/* Line 1806 of yacc.c */ -#line 1626 "go.y" + case 263: +#line 1711 "go.y" { (yyval.node) = nod(OCONTINUE, (yyvsp[(2) - (2)].node), N); } break; - case 259: - -/* Line 1806 of yacc.c */ -#line 1630 "go.y" + case 264: +#line 1715 "go.y" { (yyval.node) = nod(OPROC, (yyvsp[(2) - (2)].node), N); } break; - case 260: - -/* Line 1806 of yacc.c */ -#line 1634 "go.y" + case 265: +#line 1719 "go.y" { (yyval.node) = nod(ODEFER, (yyvsp[(2) - (2)].node), N); } break; - case 261: - -/* Line 1806 of yacc.c */ -#line 1638 "go.y" + case 266: +#line 1723 "go.y" { (yyval.node) = nod(OGOTO, (yyvsp[(2) - (2)].node), N); (yyval.node)->sym = dclstack; // context, for goto restrictions } break; - case 262: - -/* Line 1806 of yacc.c */ -#line 1643 "go.y" + case 267: +#line 1728 "go.y" { (yyval.node) = nod(ORETURN, N, N); (yyval.node)->list = (yyvsp[(2) - (2)].list); @@ -4657,10 +4326,8 @@ yyreduce: } break; - case 263: - -/* Line 1806 of yacc.c */ -#line 1662 "go.y" + case 268: +#line 1747 "go.y" { (yyval.list) = nil; if((yyvsp[(1) - (1)].node) != N) @@ -4668,10 +4335,8 @@ yyreduce: } break; - case 264: - -/* Line 1806 of yacc.c */ -#line 1668 "go.y" + case 269: +#line 1753 "go.y" { (yyval.list) = (yyvsp[(1) - (3)].list); if((yyvsp[(3) - (3)].node) != N) @@ -4679,247 +4344,195 @@ yyreduce: } break; - case 265: - -/* Line 1806 of yacc.c */ -#line 1676 "go.y" + case 270: +#line 1761 "go.y" { (yyval.list) = list1((yyvsp[(1) - (1)].node)); } break; - case 266: - -/* Line 1806 of yacc.c */ -#line 1680 "go.y" + case 271: +#line 1765 "go.y" { (yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node)); } break; - case 267: - -/* Line 1806 of yacc.c */ -#line 1686 "go.y" + case 272: +#line 1771 "go.y" { (yyval.list) = list1((yyvsp[(1) - (1)].node)); } break; - case 268: - -/* Line 1806 of yacc.c */ -#line 1690 "go.y" + case 273: +#line 1775 "go.y" { (yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node)); } break; - case 269: - -/* Line 1806 of yacc.c */ -#line 1696 "go.y" + case 274: +#line 1781 "go.y" { (yyval.list) = list1((yyvsp[(1) - (1)].node)); } break; - case 270: - -/* Line 1806 of yacc.c */ -#line 1700 "go.y" + case 275: +#line 1785 "go.y" { (yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node)); } break; - case 271: - -/* Line 1806 of yacc.c */ -#line 1706 "go.y" + case 276: +#line 1791 "go.y" { (yyval.list) = list1((yyvsp[(1) - (1)].node)); } break; - case 272: - -/* Line 1806 of yacc.c */ -#line 1710 "go.y" + case 277: +#line 1795 "go.y" { (yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node)); } break; - case 273: - -/* Line 1806 of yacc.c */ -#line 1719 "go.y" + case 278: +#line 1804 "go.y" { (yyval.list) = list1((yyvsp[(1) - (1)].node)); } break; - case 274: - -/* Line 1806 of yacc.c */ -#line 1723 "go.y" + case 279: +#line 1808 "go.y" { (yyval.list) = list1((yyvsp[(1) - (1)].node)); } break; - case 275: - -/* Line 1806 of yacc.c */ -#line 1727 "go.y" + case 280: +#line 1812 "go.y" { (yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node)); } break; - case 276: - -/* Line 1806 of yacc.c */ -#line 1731 "go.y" + case 281: +#line 1816 "go.y" { (yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node)); } break; - case 277: - -/* Line 1806 of yacc.c */ -#line 1736 "go.y" + case 282: +#line 1821 "go.y" { (yyval.list) = nil; } break; - case 278: - -/* Line 1806 of yacc.c */ -#line 1740 "go.y" + case 283: +#line 1825 "go.y" { (yyval.list) = (yyvsp[(1) - (2)].list); } break; - case 283: - -/* Line 1806 of yacc.c */ -#line 1754 "go.y" + case 288: +#line 1839 "go.y" { (yyval.node) = N; } break; - case 285: - -/* Line 1806 of yacc.c */ -#line 1760 "go.y" + case 290: +#line 1845 "go.y" { (yyval.list) = nil; } break; - case 287: - -/* Line 1806 of yacc.c */ -#line 1766 "go.y" + case 292: +#line 1851 "go.y" { (yyval.node) = N; } break; - case 289: - -/* Line 1806 of yacc.c */ -#line 1772 "go.y" + case 294: +#line 1857 "go.y" { (yyval.list) = nil; } break; - case 291: - -/* Line 1806 of yacc.c */ -#line 1778 "go.y" + case 296: +#line 1863 "go.y" { (yyval.list) = nil; } break; - case 293: - -/* Line 1806 of yacc.c */ -#line 1784 "go.y" + case 298: +#line 1869 "go.y" { (yyval.list) = nil; } break; - case 295: - -/* Line 1806 of yacc.c */ -#line 1790 "go.y" + case 300: +#line 1875 "go.y" { (yyval.val).ctype = CTxxx; } break; - case 297: - -/* Line 1806 of yacc.c */ -#line 1800 "go.y" + case 302: +#line 1885 "go.y" { importimport((yyvsp[(2) - (4)].sym), (yyvsp[(3) - (4)].val).u.sval); } break; - case 298: - -/* Line 1806 of yacc.c */ -#line 1804 "go.y" + case 303: +#line 1889 "go.y" { importvar((yyvsp[(2) - (4)].sym), (yyvsp[(3) - (4)].type)); } break; - case 299: - -/* Line 1806 of yacc.c */ -#line 1808 "go.y" + case 304: +#line 1893 "go.y" { importconst((yyvsp[(2) - (5)].sym), types[TIDEAL], (yyvsp[(4) - (5)].node)); } break; - case 300: - -/* Line 1806 of yacc.c */ -#line 1812 "go.y" + case 305: +#line 1897 "go.y" { importconst((yyvsp[(2) - (6)].sym), (yyvsp[(3) - (6)].type), (yyvsp[(5) - (6)].node)); } break; - case 301: - -/* Line 1806 of yacc.c */ -#line 1816 "go.y" + case 306: +#line 1901 "go.y" { importtype((yyvsp[(2) - (4)].type), (yyvsp[(3) - (4)].type)); } break; - case 302: - -/* Line 1806 of yacc.c */ -#line 1820 "go.y" + case 307: +#line 1905 "go.y" { - if((yyvsp[(2) - (4)].node) == N) + if((yyvsp[(2) - (4)].node) == N) { + dclcontext = PEXTERN; // since we skip the funcbody below break; + } (yyvsp[(2) - (4)].node)->inl = (yyvsp[(3) - (4)].list); @@ -4928,45 +4541,37 @@ yyreduce: if(debug['E']) { print("import [%Z] func %lN \n", importpkg->path, (yyvsp[(2) - (4)].node)); - if(debug['l'] > 2 && (yyvsp[(2) - (4)].node)->inl) + if(debug['m'] > 2 && (yyvsp[(2) - (4)].node)->inl) print("inl body:%+H\n", (yyvsp[(2) - (4)].node)->inl); } } break; - case 303: - -/* Line 1806 of yacc.c */ -#line 1838 "go.y" + case 308: +#line 1925 "go.y" { (yyval.sym) = (yyvsp[(1) - (1)].sym); structpkg = (yyval.sym)->pkg; } break; - case 304: - -/* Line 1806 of yacc.c */ -#line 1845 "go.y" + case 309: +#line 1932 "go.y" { (yyval.type) = pkgtype((yyvsp[(1) - (1)].sym)); importsym((yyvsp[(1) - (1)].sym), OTYPE); } break; - case 310: - -/* Line 1806 of yacc.c */ -#line 1865 "go.y" + case 315: +#line 1952 "go.y" { (yyval.type) = pkgtype((yyvsp[(1) - (1)].sym)); } break; - case 311: - -/* Line 1806 of yacc.c */ -#line 1869 "go.y" + case 316: +#line 1956 "go.y" { // predefined name like uint8 (yyvsp[(1) - (1)].sym) = pkglookup((yyvsp[(1) - (1)].sym)->name, builtinpkg); @@ -4978,64 +4583,50 @@ yyreduce: } break; - case 312: - -/* Line 1806 of yacc.c */ -#line 1879 "go.y" + case 317: +#line 1966 "go.y" { (yyval.type) = aindex(N, (yyvsp[(3) - (3)].type)); } break; - case 313: - -/* Line 1806 of yacc.c */ -#line 1883 "go.y" + case 318: +#line 1970 "go.y" { (yyval.type) = aindex(nodlit((yyvsp[(2) - (4)].val)), (yyvsp[(4) - (4)].type)); } break; - case 314: - -/* Line 1806 of yacc.c */ -#line 1887 "go.y" + case 319: +#line 1974 "go.y" { (yyval.type) = maptype((yyvsp[(3) - (5)].type), (yyvsp[(5) - (5)].type)); } break; - case 315: - -/* Line 1806 of yacc.c */ -#line 1891 "go.y" + case 320: +#line 1978 "go.y" { (yyval.type) = tostruct((yyvsp[(3) - (4)].list)); } break; - case 316: - -/* Line 1806 of yacc.c */ -#line 1895 "go.y" + case 321: +#line 1982 "go.y" { (yyval.type) = tointerface((yyvsp[(3) - (4)].list)); } break; - case 317: - -/* Line 1806 of yacc.c */ -#line 1899 "go.y" + case 322: +#line 1986 "go.y" { (yyval.type) = ptrto((yyvsp[(2) - (2)].type)); } break; - case 318: - -/* Line 1806 of yacc.c */ -#line 1903 "go.y" + case 323: +#line 1990 "go.y" { (yyval.type) = typ(TCHAN); (yyval.type)->type = (yyvsp[(2) - (2)].type); @@ -5043,10 +4634,8 @@ yyreduce: } break; - case 319: - -/* Line 1806 of yacc.c */ -#line 1909 "go.y" + case 324: +#line 1996 "go.y" { (yyval.type) = typ(TCHAN); (yyval.type)->type = (yyvsp[(3) - (4)].type); @@ -5054,10 +4643,8 @@ yyreduce: } break; - case 320: - -/* Line 1806 of yacc.c */ -#line 1915 "go.y" + case 325: +#line 2002 "go.y" { (yyval.type) = typ(TCHAN); (yyval.type)->type = (yyvsp[(3) - (3)].type); @@ -5065,10 +4652,8 @@ yyreduce: } break; - case 321: - -/* Line 1806 of yacc.c */ -#line 1923 "go.y" + case 326: +#line 2010 "go.y" { (yyval.type) = typ(TCHAN); (yyval.type)->type = (yyvsp[(3) - (3)].type); @@ -5076,19 +4661,15 @@ yyreduce: } break; - case 322: - -/* Line 1806 of yacc.c */ -#line 1931 "go.y" + case 327: +#line 2018 "go.y" { (yyval.type) = functype(nil, (yyvsp[(3) - (5)].list), (yyvsp[(5) - (5)].list)); } break; - case 323: - -/* Line 1806 of yacc.c */ -#line 1937 "go.y" + case 328: +#line 2024 "go.y" { (yyval.node) = nod(ODCLFIELD, N, typenod((yyvsp[(2) - (3)].type))); if((yyvsp[(1) - (3)].sym)) @@ -5097,10 +4678,8 @@ yyreduce: } break; - case 324: - -/* Line 1806 of yacc.c */ -#line 1944 "go.y" + case 329: +#line 2031 "go.y" { Type *t; @@ -5116,10 +4695,8 @@ yyreduce: } break; - case 325: - -/* Line 1806 of yacc.c */ -#line 1960 "go.y" + case 330: +#line 2047 "go.y" { Sym *s; @@ -5137,64 +4714,50 @@ yyreduce: } break; - case 326: - -/* Line 1806 of yacc.c */ -#line 1978 "go.y" + case 331: +#line 2065 "go.y" { (yyval.node) = nod(ODCLFIELD, newname((yyvsp[(1) - (5)].sym)), typenod(functype(fakethis(), (yyvsp[(3) - (5)].list), (yyvsp[(5) - (5)].list)))); } break; - case 327: - -/* Line 1806 of yacc.c */ -#line 1982 "go.y" + case 332: +#line 2069 "go.y" { (yyval.node) = nod(ODCLFIELD, N, typenod((yyvsp[(1) - (1)].type))); } break; - case 328: - -/* Line 1806 of yacc.c */ -#line 1987 "go.y" + case 333: +#line 2074 "go.y" { (yyval.list) = nil; } break; - case 330: - -/* Line 1806 of yacc.c */ -#line 1994 "go.y" + case 335: +#line 2081 "go.y" { (yyval.list) = (yyvsp[(2) - (3)].list); } break; - case 331: - -/* Line 1806 of yacc.c */ -#line 1998 "go.y" + case 336: +#line 2085 "go.y" { (yyval.list) = list1(nod(ODCLFIELD, N, typenod((yyvsp[(1) - (1)].type)))); } break; - case 332: - -/* Line 1806 of yacc.c */ -#line 2008 "go.y" + case 337: +#line 2095 "go.y" { (yyval.node) = nodlit((yyvsp[(1) - (1)].val)); } break; - case 333: - -/* Line 1806 of yacc.c */ -#line 2012 "go.y" + case 338: +#line 2099 "go.y" { (yyval.node) = nodlit((yyvsp[(2) - (2)].val)); switch((yyval.node)->val.ctype){ @@ -5211,10 +4774,8 @@ yyreduce: } break; - case 334: - -/* Line 1806 of yacc.c */ -#line 2027 "go.y" + case 339: +#line 2114 "go.y" { (yyval.node) = oldname(pkglookup((yyvsp[(1) - (1)].sym)->name, builtinpkg)); if((yyval.node)->op != OLITERAL) @@ -5222,91 +4783,67 @@ yyreduce: } break; - case 336: - -/* Line 1806 of yacc.c */ -#line 2036 "go.y" + case 341: +#line 2123 "go.y" { if((yyvsp[(2) - (5)].node)->val.ctype == CTRUNE && (yyvsp[(4) - (5)].node)->val.ctype == CTINT) { (yyval.node) = (yyvsp[(2) - (5)].node); mpaddfixfix((yyvsp[(2) - (5)].node)->val.u.xval, (yyvsp[(4) - (5)].node)->val.u.xval, 0); break; } + (yyvsp[(4) - (5)].node)->val.u.cval->real = (yyvsp[(4) - (5)].node)->val.u.cval->imag; + mpmovecflt(&(yyvsp[(4) - (5)].node)->val.u.cval->imag, 0.0); (yyval.node) = nodcplxlit((yyvsp[(2) - (5)].node)->val, (yyvsp[(4) - (5)].node)->val); } break; - case 339: - -/* Line 1806 of yacc.c */ -#line 2050 "go.y" + case 344: +#line 2139 "go.y" { (yyval.list) = list1((yyvsp[(1) - (1)].node)); } break; - case 340: - -/* Line 1806 of yacc.c */ -#line 2054 "go.y" + case 345: +#line 2143 "go.y" { (yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node)); } break; - case 341: - -/* Line 1806 of yacc.c */ -#line 2060 "go.y" + case 346: +#line 2149 "go.y" { (yyval.list) = list1((yyvsp[(1) - (1)].node)); } break; - case 342: - -/* Line 1806 of yacc.c */ -#line 2064 "go.y" + case 347: +#line 2153 "go.y" { (yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node)); } break; - case 343: - -/* Line 1806 of yacc.c */ -#line 2070 "go.y" + case 348: +#line 2159 "go.y" { (yyval.list) = list1((yyvsp[(1) - (1)].node)); } break; - case 344: - -/* Line 1806 of yacc.c */ -#line 2074 "go.y" + case 349: +#line 2163 "go.y" { (yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node)); } break; - -/* Line 1806 of yacc.c */ -#line 5298 "y.tab.c" +/* Line 1267 of yacc.c. */ +#line 4846 "y.tab.c" default: break; } - /* User semantic actions sometimes alter yychar, and that requires - that yytoken be updated with the new translation. We take the - approach of translating immediately before every use of yytoken. - One alternative is translating here after every semantic action, - but that translation would be missed if the semantic action invokes - YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or - if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an - incorrect destructor might then be invoked immediately. In the - case of YYERROR or YYBACKUP, subsequent parser actions might lead - to an incorrect destructor call or verbose syntax error message - before the lookahead is translated. */ YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); YYPOPSTACK (yylen); @@ -5315,6 +4852,7 @@ yyreduce: *++yyvsp = yyval; + /* Now `shift' the result of the reduction. Determine what state that goes to, based on the state we popped back to and the rule number reduced by. */ @@ -5334,10 +4872,6 @@ yyreduce: | yyerrlab -- here on detecting error | `------------------------------------*/ yyerrlab: - /* Make sure we have latest lookahead translation. See comments at - user semantic actions for why this is necessary. */ - yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar); - /* If not already recovering from an error, report this error. */ if (!yyerrstatus) { @@ -5345,36 +4879,37 @@ yyerrlab: #if ! YYERROR_VERBOSE yyerror (YY_("syntax error")); #else -# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \ - yyssp, yytoken) { - char *yymsgp = YY_("syntax error"); - int yysyntax_error_status; - yysyntax_error_status = YYSYNTAX_ERROR; - if (yysyntax_error_status == 0) - yymsgp = yymsg; - else if (yysyntax_error_status == 1) - { - if (yymsg != yymsgbuf) - YYSTACK_FREE (yymsg); - yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc); - if (!yymsg) - { - yymsg = yymsgbuf; - yymsg_alloc = sizeof yymsgbuf; - yysyntax_error_status = 2; - } - else - { - yysyntax_error_status = YYSYNTAX_ERROR; - yymsgp = yymsg; - } - } - yyerror (yymsgp); - if (yysyntax_error_status == 2) - goto yyexhaustedlab; + YYSIZE_T yysize = yysyntax_error (0, yystate, yychar); + if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM) + { + YYSIZE_T yyalloc = 2 * yysize; + if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM)) + yyalloc = YYSTACK_ALLOC_MAXIMUM; + if (yymsg != yymsgbuf) + YYSTACK_FREE (yymsg); + yymsg = (char *) YYSTACK_ALLOC (yyalloc); + if (yymsg) + yymsg_alloc = yyalloc; + else + { + yymsg = yymsgbuf; + yymsg_alloc = sizeof yymsgbuf; + } + } + + if (0 < yysize && yysize <= yymsg_alloc) + { + (void) yysyntax_error (yymsg, yystate, yychar); + yyerror (yymsg); + } + else + { + yyerror (YY_("syntax error")); + if (yysize != 0) + goto yyexhaustedlab; + } } -# undef YYSYNTAX_ERROR #endif } @@ -5382,7 +4917,7 @@ yyerrlab: if (yyerrstatus == 3) { - /* If just tried and failed to reuse lookahead token after an + /* If just tried and failed to reuse look-ahead token after an error, discard it. */ if (yychar <= YYEOF) @@ -5399,7 +4934,7 @@ yyerrlab: } } - /* Else will try to reuse lookahead token after shifting the error + /* Else will try to reuse look-ahead token after shifting the error token. */ goto yyerrlab1; @@ -5433,7 +4968,7 @@ yyerrlab1: for (;;) { yyn = yypact[yystate]; - if (!yypact_value_is_default (yyn)) + if (yyn != YYPACT_NINF) { yyn += YYTERROR; if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) @@ -5456,6 +4991,9 @@ yyerrlab1: YY_STACK_PRINT (yyss, yyssp); } + if (yyn == YYFINAL) + YYACCEPT; + *++yyvsp = yylval; @@ -5480,7 +5018,7 @@ yyabortlab: yyresult = 1; goto yyreturn; -#if !defined(yyoverflow) || YYERROR_VERBOSE +#ifndef yyoverflow /*-------------------------------------------------. | yyexhaustedlab -- memory exhaustion comes here. | `-------------------------------------------------*/ @@ -5491,14 +5029,9 @@ yyexhaustedlab: #endif yyreturn: - if (yychar != YYEMPTY) - { - /* Make sure we have latest lookahead translation. See comments at - user semantic actions for why this is necessary. */ - yytoken = YYTRANSLATE (yychar); - yydestruct ("Cleanup: discarding lookahead", - yytoken, &yylval); - } + if (yychar != YYEOF && yychar != YYEMPTY) + yydestruct ("Cleanup: discarding lookahead", + yytoken, &yylval); /* Do not reclaim the symbols of the rule which action triggered this YYABORT or YYACCEPT. */ YYPOPSTACK (yylen); @@ -5522,9 +5055,7 @@ yyreturn: } - -/* Line 2067 of yacc.c */ -#line 2078 "go.y" +#line 2167 "go.y" static void diff --git a/src/cmd/gc/y.tab.h b/src/cmd/gc/y.tab.h index bc6c47d6d..d01fbe198 100644 --- a/src/cmd/gc/y.tab.h +++ b/src/cmd/gc/y.tab.h @@ -1,21 +1,24 @@ -/* A Bison parser, made by GNU Bison 2.5. */ +/* A Bison parser, made by GNU Bison 2.3. */ -/* Bison interface for Yacc-like parsers in C - - Copyright (C) 1984, 1989-1990, 2000-2011 Free Software Foundation, Inc. - - This program is free software: you can redistribute it and/or modify +/* Skeleton interface for Bison's Yacc-like parsers in C + + Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 + Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - + the Free Software Foundation; either version 2, or (at your option) + any later version. + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. */ + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work @@ -26,11 +29,10 @@ special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. - + This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ - /* Tokens. */ #ifndef YYTOKENTYPE # define YYTOKENTYPE @@ -39,10 +41,10 @@ enum yytokentype { LLITERAL = 258, LASOP = 259, - LBREAK = 260, - LCASE = 261, - LCHAN = 262, - LCOLAS = 263, + LCOLAS = 260, + LBREAK = 261, + LCASE = 262, + LCHAN = 263, LCONST = 264, LCONTINUE = 265, LDDD = 266, @@ -91,10 +93,10 @@ /* Tokens. */ #define LLITERAL 258 #define LASOP 259 -#define LBREAK 260 -#define LCASE 261 -#define LCHAN 262 -#define LCOLAS 263 +#define LCOLAS 260 +#define LBREAK 261 +#define LCASE 262 +#define LCHAN 263 #define LCONST 264 #define LCONTINUE 265 #define LDDD 266 @@ -144,28 +146,22 @@ #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED typedef union YYSTYPE -{ - -/* Line 2068 of yacc.c */ #line 28 "go.y" - +{ Node* node; NodeList* list; Type* type; Sym* sym; struct Val val; int i; - - - -/* Line 2068 of yacc.c */ -#line 163 "y.tab.h" -} YYSTYPE; -# define YYSTYPE_IS_TRIVIAL 1 +} +/* Line 1529 of yacc.c. */ +#line 160 "y.tab.h" + YYSTYPE; # define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 +# define YYSTYPE_IS_TRIVIAL 1 #endif extern YYSTYPE yylval; - diff --git a/src/cmd/gc/yerr.h b/src/cmd/gc/yerr.h index 588890d0e..e7eb6516c 100644 --- a/src/cmd/gc/yerr.h +++ b/src/cmd/gc/yerr.h @@ -26,7 +26,7 @@ static struct { 237, ';', "unexpected semicolon or newline before {", - 474, LBODY, + 475, LBODY, "unexpected semicolon or newline before {", 22, '{', @@ -44,7 +44,7 @@ static struct { 37, ',', "unexpected comma in channel type", - 437, LELSE, + 438, LELSE, "unexpected semicolon or newline before else", 257, ',', @@ -65,9 +65,12 @@ static struct { 425, ';', "need trailing comma before newline in composite literal", + 436, ';', + "need trailing comma before newline in composite literal", + 112, LNAME, "nested func not allowed", - 615, ';', + 642, ';', "else must be followed by if or statement block" }; |