]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: don't inline from norace packages in race mode
authorCherry Mui <cherryyz@google.com>
Tue, 16 May 2023 23:52:41 +0000 (19:52 -0400)
committerCherry Mui <cherryyz@google.com>
Wed, 17 May 2023 14:48:16 +0000 (14:48 +0000)
In race mode (or other instrumentation mode), if the caller is in
a regular package and the callee is in a norace (or noinstrument)
package, don't inline. Otherwise, when the caller is instumented
it will also affect the inlined callee.

An example is sync.(*Mutex).Unlock, which is typically not inlined
but with PGO it can be inlined into a regular function, which is
then get instrumented. But the rest of the sync package, in
particular, the Lock function is not instrumented, causing the
race detector to signal false race.

Change-Id: Ia78bb602c6da63a34ec2909b9a82646bf20873f3
Reviewed-on: https://go-review.googlesource.com/c/go/+/495595
Run-TryBot: Cherry Mui <cherryyz@google.com>
Reviewed-by: Michael Pratt <mpratt@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>

src/cmd/compile/internal/inline/inl.go
src/cmd/compile/internal/types/type.go

index cd856b9a9ad34fafd850c66aa54c57e2a69b26b6..f8b5c4abae510639ba8a5febe8d54d5f488636d5 100644 (file)
@@ -1041,7 +1041,7 @@ func mkinlcall(n *ir.CallExpr, fn *ir.Func, bigCaller bool, inlCalls *[]*ir.Inli
                return n
        }
 
-       if base.Flag.Cfg.Instrumenting && types.IsRuntimePkg(fn.Sym().Pkg) {
+       if base.Flag.Cfg.Instrumenting && types.IsNoInstrumentPkg(fn.Sym().Pkg) {
                // Runtime package must not be instrumented.
                // Instrument skips runtime package. However, some runtime code can be
                // inlined into other packages and instrumented there. To avoid this,
@@ -1050,6 +1050,9 @@ func mkinlcall(n *ir.CallExpr, fn *ir.Func, bigCaller bool, inlCalls *[]*ir.Inli
                // which lead to false race reports on m contents.
                return n
        }
+       if base.Flag.Race && types.IsNoRacePkg(fn.Sym().Pkg) {
+               return n
+       }
 
        parent := base.Ctxt.PosTable.Pos(n.Pos()).Base().InliningIndex()
        sym := fn.Linksym()
index 9775d37b396f42e02988804b3c1bb66d6ce1d7ae..c390b8194b895df892c155923a7eba5a238f7eb5 100644 (file)
@@ -1863,6 +1863,28 @@ func IsTypePkg(p *Pkg) bool {
        return p == typepkg
 }
 
+// IsNoInstrumentPkg reports whether p is a package that
+// should not be instrumented.
+func IsNoInstrumentPkg(p *Pkg) bool {
+       for _, np := range base.NoInstrumentPkgs {
+               if p.Path == np {
+                       return true
+               }
+       }
+       return false
+}
+
+// IsNoRacePkg reports whether p is a package that
+// should not be race instrumented.
+func IsNoRacePkg(p *Pkg) bool {
+       for _, np := range base.NoRacePkgs {
+               if p.Path == np {
+                       return true
+               }
+       }
+       return false
+}
+
 // ReceiverBaseType returns the underlying type, if any,
 // that owns methods with receiver parameter t.
 // The result is either a named type or an anonymous struct.