diff options
| author | Dhananjay Nakrani <dhananjaynakrani@gmail.com> | 2016-10-17 14:17:46 -0700 |
|---|---|---|
| committer | Matthew Dempsky <mdempsky@google.com> | 2016-10-18 20:11:01 +0000 |
| commit | 8b3194ac8fd8436bf4bfd252de58ab81154f334d (patch) | |
| tree | 510422b61fc4de3013e0f4a1a653711f150966f5 /src | |
| parent | 2b687a7df854f3c88b266b6cec59a207a45c2353 (diff) | |
| download | go-8b3194ac8fd8436bf4bfd252de58ab81154f334d.tar.xz | |
cmd/compile: fix code duplication in race-instrumentation
instrumentnode() accidentally copies parent's already-instrumented nodes
into child's Ninit block. This generates repeated code in race-instrumentation.
This case surfaces only when it duplicates inline-labels, because of
compile time error. In other cases, it silently generates incorrect
instrumented code. This change prevents it from doing so.
Fixes #17449.
Change-Id: Icddf2198990442166307e176b7e20aa0cf6c171c
Reviewed-on: https://go-review.googlesource.com/31317
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Diffstat (limited to 'src')
| -rw-r--r-- | src/cmd/compile/internal/gc/racewalk.go | 39 |
1 files changed, 12 insertions, 27 deletions
diff --git a/src/cmd/compile/internal/gc/racewalk.go b/src/cmd/compile/internal/gc/racewalk.go index 8f57ef33fe..c8ab6038aa 100644 --- a/src/cmd/compile/internal/gc/racewalk.go +++ b/src/cmd/compile/internal/gc/racewalk.go @@ -145,36 +145,21 @@ func instrumentnode(np **Node, init *Nodes, wr int, skip int) { goto ret case OBLOCK: - var out []*Node ls := n.List.Slice() - for i := 0; i < len(ls); i++ { - switch ls[i].Op { - case OCALLFUNC, OCALLMETH, OCALLINTER: - instrumentnode(&ls[i], &ls[i].Ninit, 0, 0) - out = append(out, ls[i]) - // Scan past OAS nodes copying results off stack. - // Those must not be instrumented, because the - // instrumentation calls will smash the results. - // The assignments are to temporaries, so they cannot - // be involved in races and need not be instrumented. - for i+1 < len(ls) && ls[i+1].Op == OAS && iscallret(ls[i+1].Right) { - i++ - out = append(out, ls[i]) - } - default: - var outn Nodes - outn.Set(out) - instrumentnode(&ls[i], &outn, 0, 0) - if ls[i].Op != OAS && ls[i].Op != OASWB && ls[i].Op != OAS2FUNC || ls[i].Ninit.Len() == 0 { - out = append(outn.Slice(), ls[i]) - } else { - // Splice outn onto end of ls[i].Ninit - ls[i].Ninit.AppendNodes(&outn) - out = append(out, ls[i]) - } + afterCall := false + for i := range ls { + op := ls[i].Op + // Scan past OAS nodes copying results off stack. + // Those must not be instrumented, because the + // instrumentation calls will smash the results. + // The assignments are to temporaries, so they cannot + // be involved in races and need not be instrumented. + if afterCall && op == OAS && iscallret(ls[i].Right) { + continue } + instrumentnode(&ls[i], &ls[i].Ninit, 0, 0) + afterCall = (op == OCALLFUNC || op == OCALLMETH || op == OCALLINTER) } - n.List.Set(out) goto ret case ODEFER: |
