diff options
-rw-r--r-- | doc/GoCourseDay1.pdf | bin | 801121 -> 904237 bytes | |||
-rw-r--r-- | doc/GoCourseDay2.pdf | bin | 806917 -> 268707 bytes | |||
-rw-r--r-- | doc/GoCourseDay3.pdf | bin | 530749 -> 178003 bytes | |||
-rw-r--r-- | doc/devel/release.html | 1 | ||||
-rw-r--r-- | doc/docs.html | 13 | ||||
-rw-r--r-- | doc/go_tutorial.html | 3 | ||||
-rw-r--r-- | doc/go_tutorial.txt | 3 | ||||
-rw-r--r-- | src/cmd/5g/gsubr.c | 58 | ||||
-rw-r--r-- | src/cmd/6g/gsubr.c | 38 | ||||
-rw-r--r-- | src/cmd/8g/gsubr.c | 38 | ||||
-rw-r--r-- | src/cmd/gc/dcl.c | 5 | ||||
-rw-r--r-- | src/cmd/gc/gen.c | 1 | ||||
-rw-r--r-- | src/cmd/gc/go.h | 3 | ||||
-rw-r--r-- | src/pkg/reflect/all_test.go | 4 | ||||
-rw-r--r-- | test/fixedbugs/bug344.go | 22 |
15 files changed, 183 insertions, 6 deletions
diff --git a/doc/GoCourseDay1.pdf b/doc/GoCourseDay1.pdf Binary files differindex bae12d2ad..c2c8c4a7d 100644 --- a/doc/GoCourseDay1.pdf +++ b/doc/GoCourseDay1.pdf diff --git a/doc/GoCourseDay2.pdf b/doc/GoCourseDay2.pdf Binary files differindex d05486e30..0d82ba4d3 100644 --- a/doc/GoCourseDay2.pdf +++ b/doc/GoCourseDay2.pdf diff --git a/doc/GoCourseDay3.pdf b/doc/GoCourseDay3.pdf Binary files differindex 8f95806b2..5a5463ba2 100644 --- a/doc/GoCourseDay3.pdf +++ b/doc/GoCourseDay3.pdf diff --git a/doc/devel/release.html b/doc/devel/release.html index 8f28945ef..84ca622fa 100644 --- a/doc/devel/release.html +++ b/doc/devel/release.html @@ -162,6 +162,7 @@ For other uses, see the <a href="/pkg/runtime/pprof/">runtime/pprof</a> document <h3 id="r57.minor">Minor revisions</h3> <p>r57.1 fixes a <a href="http://code.google.com/p/go/source/detail?r=ff2bc62726e7145eb2ecc1e0f076998e4a8f86f0">nil pointer dereference in http.FormFile</a>.</p> +<p>r57.2 fixes a <a href="http://code.google.com/p/go/source/detail?r=063b0ff67d8277df03c956208abc068076818dae">use of uninitialized memory in programs that misuse <code>goto</code></a>.</p> <h2 id="r56">r56 (released 2011/03/16)</h2> diff --git a/doc/docs.html b/doc/docs.html index e8152bb35..d4e78446f 100644 --- a/doc/docs.html +++ b/doc/docs.html @@ -23,6 +23,17 @@ concepts: syntax, types, allocation, constants, I/O, sorting, printing, goroutines, and channels. </p> +<h3 id="course_notes">Course Notes</h3> +<p> +Slides from a 3-day course about the Go programming language. +A more thorough introduction than the tutorial. +</p> +<ul> +<li><a href="GoCourseDay1.pdf">Day 1: Basics</a> <small>[270KB PDF]</small> +<li><a href="GoCourseDay2.pdf">Day 2: Types, Methods, Interfaces</a> <small>[270KB PDF]</small> +<li><a href="GoCourseDay3.pdf">Day 3: Concurrency and Communication</a> <small>[180KB PDF]</small> +</ul> + <h3 id="effective_go"><a href="effective_go.html">Effective Go</a></h3> <p> A document that gives tips for writing clear, idiomatic Go code. @@ -179,7 +190,7 @@ from Hoareās 1978 paper to Go provides insight into how and why Go works as it does. </i></p> -<h3 id="emerging_go"><a href="talks/gofrontend-gcc-summit-2010.pdf">The Go frontend for GCC</a></h3> +<h3 id="go_frontend_gcc"><a href="talks/gofrontend-gcc-summit-2010.pdf">The Go frontend for GCC</a></h3> <p> A description of the Go language frontend for gcc. Ian Lance Taylor's paper delivered at the GCC Summit 2010. diff --git a/doc/go_tutorial.html b/doc/go_tutorial.html index c87254ecb..4470f2748 100644 --- a/doc/go_tutorial.html +++ b/doc/go_tutorial.html @@ -10,8 +10,7 @@ After you've read this tutorial, you should look at which digs deeper into how the language is used and talks about the style and idioms of programming in Go. Also, slides from a 3-day course about Go are available. -Although they're badly out of date, they provide some -background and a lot of examples: +They provide some background and a lot of examples: <a href='/doc/GoCourseDay1.pdf'>Day 1</a>, <a href='/doc/GoCourseDay2.pdf'>Day 2</a>, <a href='/doc/GoCourseDay3.pdf'>Day 3</a>. diff --git a/doc/go_tutorial.txt b/doc/go_tutorial.txt index ab02baf2c..3e0b21d99 100644 --- a/doc/go_tutorial.txt +++ b/doc/go_tutorial.txt @@ -11,8 +11,7 @@ After you've read this tutorial, you should look at which digs deeper into how the language is used and talks about the style and idioms of programming in Go. Also, slides from a 3-day course about Go are available. -Although they're badly out of date, they provide some -background and a lot of examples: +They provide some background and a lot of examples: <a href='/doc/GoCourseDay1.pdf'>Day 1</a>, <a href='/doc/GoCourseDay2.pdf'>Day 2</a>, <a href='/doc/GoCourseDay3.pdf'>Day 3</a>. diff --git a/src/cmd/5g/gsubr.c b/src/cmd/5g/gsubr.c index 83a9949d6..57cb56a64 100644 --- a/src/cmd/5g/gsubr.c +++ b/src/cmd/5g/gsubr.c @@ -125,6 +125,64 @@ newplist(void) } void +clearstk(void) +{ + Plist *pl; + Prog *p, *p1, *p2, *p3; + Node dst, end, zero, con; + + if(plast->firstpc->to.offset <= 0) + return; + + // reestablish context for inserting code + // at beginning of function. + pl = plast; + p1 = pl->firstpc; + p2 = p1->link; + pc = mal(sizeof(*pc)); + clearp(pc); + p1->link = pc; + + // zero stack frame + + // MOVW $4(SP), R1 + nodreg(&dst, types[tptr], 1); + p = gins(AMOVW, N, &dst); + p->from.type = D_CONST; + p->from.reg = REGSP; + p->from.offset = 4; + + // MOVW $n(R1), R2 + nodreg(&end, types[tptr], 2); + p = gins(AMOVW, N, &end); + p->from.type = D_CONST; + p->from.reg = 1; + p->from.offset = p1->to.offset; + + // MOVW $0, R3 + nodreg(&zero, types[TUINT32], 3); + nodconst(&con, types[TUINT32], 0); + gmove(&con, &zero); + + // L: + // MOVW.P R3, 0(R1) +4 + // CMP R1, R2 + // BNE L + p = gins(AMOVW, &zero, &dst); + p->to.type = D_OREG; + p->to.offset = 4; + p->scond |= C_PBIT; + p3 = p; + p = gins(ACMP, &dst, N); + raddr(&end, p); + patch(gbranch(ABNE, T), p3); + + // continue with original code. + gins(ANOP, N, N)->link = p2; + pc = P; +} + +void gused(Node *n) { gins(ANOP, n, N); // used diff --git a/src/cmd/6g/gsubr.c b/src/cmd/6g/gsubr.c index c3dac1fdc..78b8c4351 100644 --- a/src/cmd/6g/gsubr.c +++ b/src/cmd/6g/gsubr.c @@ -121,6 +121,44 @@ newplist(void) } void +clearstk(void) +{ + Plist *pl; + Prog *p1, *p2; + Node sp, di, cx, con, ax; + + if((uint32)plast->firstpc->to.offset <= 0) + return; + + // reestablish context for inserting code + // at beginning of function. + pl = plast; + p1 = pl->firstpc; + p2 = p1->link; + pc = mal(sizeof(*pc)); + clearp(pc); + p1->link = pc; + + // zero stack frame + nodreg(&sp, types[tptr], D_SP); + nodreg(&di, types[tptr], D_DI); + nodreg(&cx, types[TUINT64], D_CX); + nodconst(&con, types[TUINT64], (uint32)p1->to.offset / widthptr); + gins(ACLD, N, N); + gins(AMOVQ, &sp, &di); + gins(AMOVQ, &con, &cx); + nodconst(&con, types[TUINT64], 0); + nodreg(&ax, types[TUINT64], D_AX); + gins(AMOVQ, &con, &ax); + gins(AREP, N, N); + gins(ASTOSQ, N, N); + + // continue with original code. + gins(ANOP, N, N)->link = p2; + pc = P; +} + +void gused(Node *n) { gins(ANOP, n, N); // used diff --git a/src/cmd/8g/gsubr.c b/src/cmd/8g/gsubr.c index 8ed7e5564..ae9901eeb 100644 --- a/src/cmd/8g/gsubr.c +++ b/src/cmd/8g/gsubr.c @@ -123,6 +123,44 @@ newplist(void) } void +clearstk(void) +{ + Plist *pl; + Prog *p1, *p2; + Node sp, di, cx, con, ax; + + if(plast->firstpc->to.offset <= 0) + return; + + // reestablish context for inserting code + // at beginning of function. + pl = plast; + p1 = pl->firstpc; + p2 = p1->link; + pc = mal(sizeof(*pc)); + clearp(pc); + p1->link = pc; + + // zero stack frame + nodreg(&sp, types[tptr], D_SP); + nodreg(&di, types[tptr], D_DI); + nodreg(&cx, types[TUINT32], D_CX); + nodconst(&con, types[TUINT32], p1->to.offset / widthptr); + gins(ACLD, N, N); + gins(AMOVL, &sp, &di); + gins(AMOVL, &con, &cx); + nodconst(&con, types[TUINT32], 0); + nodreg(&ax, types[TUINT32], D_AX); + gins(AMOVL, &con, &ax); + gins(AREP, N, N); + gins(ASTOSL, N, N); + + // continue with original code. + gins(ANOP, N, N)->link = p2; + pc = P; +} + +void gused(Node *n) { gins(ANOP, n, N); // used diff --git a/src/cmd/gc/dcl.c b/src/cmd/gc/dcl.c index 99af18d9f..8e790ef08 100644 --- a/src/cmd/gc/dcl.c +++ b/src/cmd/gc/dcl.c @@ -1233,9 +1233,14 @@ funccompile(Node *n, int isclosure) stksize = 0; dclcontext = PAUTO; funcdepth = n->funcdepth + 1; + hasgoto = 0; compile(n); + if(hasgoto) + clearstk(); curfn = nil; funcdepth = 0; dclcontext = PEXTERN; } + + diff --git a/src/cmd/gc/gen.c b/src/cmd/gc/gen.c index 8ad6c437d..857fcbef9 100644 --- a/src/cmd/gc/gen.c +++ b/src/cmd/gc/gen.c @@ -205,6 +205,7 @@ gen(Node *n) break; case OGOTO: + hasgoto = 1; newlab(OGOTO, n, N); gjmp(P); break; diff --git a/src/cmd/gc/go.h b/src/cmd/gc/go.h index f58b76789..4b4e8fcd1 100644 --- a/src/cmd/gc/go.h +++ b/src/cmd/gc/go.h @@ -1246,3 +1246,6 @@ void zhist(Biobuf *b, int line, vlong offset); void zname(Biobuf *b, Sym *s, int t); void data(void); void text(void); + +EXTERN int hasgoto; +void clearstk(void); diff --git a/src/pkg/reflect/all_test.go b/src/pkg/reflect/all_test.go index dee3f4915..e20e03f50 100644 --- a/src/pkg/reflect/all_test.go +++ b/src/pkg/reflect/all_test.go @@ -1459,7 +1459,9 @@ func noAlloc(t *testing.T, n int, f func(int)) { for j := 0; j < n; j++ { f(j) } - if runtime.MemStats.Mallocs != 0 { + // A few allocs may happen in the testing package when GOMAXPROCS > 1, so don't + // require zero mallocs. + if runtime.MemStats.Mallocs > 5 { t.Fatalf("%d mallocs after %d iterations", runtime.MemStats.Mallocs, n) } } diff --git a/test/fixedbugs/bug344.go b/test/fixedbugs/bug344.go new file mode 100644 index 000000000..2a20dcf6f --- /dev/null +++ b/test/fixedbugs/bug344.go @@ -0,0 +1,22 @@ +// $G $D/$F.go && $L $F.$A && ./$A.out || echo BUG: bug344 + +// 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. + +package main + +import "fmt" + +func main() { + // invalid use of goto. + // do whatever you like, just don't crash. + i := 42 + a := []*int{&i, &i, &i, &i} + x := a[0] + goto start + for _, x = range a { + start: + fmt.Sprint(*x) + } +} |