]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/internal/objabi,test: use correct GOEXPERIMENT build tags in test/run.go
authorAustin Clements <austin@google.com>
Wed, 14 Apr 2021 17:25:31 +0000 (13:25 -0400)
committerRuss Cox <rsc@golang.org>
Fri, 16 Apr 2021 03:16:55 +0000 (03:16 +0000)
Currently, run.go sets GOEXPERIMENT build tags based on the
*difference* from the baseline experiment configuration, rather than
the absolute experiment configuration. This differs from cmd/go. As a
result, if we set a baseline configuration and don't override it with
a GOEXPERIMENT setting, run.go won't set any GOEXPERIMENT build tags,
instead of setting the tags corresponding to the baseline
configuration.

Fix this by making compile -V=goexperiment produce the full
GOEXPERIMENT configuration, which run.go can then use to set exactly
the right set of build tags.

For #40724.

Change-Id: Ieda6ea62f1a1fabbe8d749d6d09c198fd5ca8377
Reviewed-on: https://go-review.googlesource.com/c/go/+/310171
Trust: Austin Clements <austin@google.com>
Run-TryBot: Austin Clements <austin@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
src/cmd/internal/objabi/exp.go
src/cmd/internal/objabi/flag.go
test/run.go

index 9eb3e431b394dadafd08a67d6108f6099b556769..3371c6c8f86751a307dbbb8f009e95e451ef4ce0 100644 (file)
@@ -108,8 +108,9 @@ func parseExperiments() goexperiment.Flags {
 
 // expList returns the list of lower-cased experiment names for
 // experiments that differ from base. base may be nil to indicate no
-// experiments.
-func expList(exp, base *goexperiment.Flags) []string {
+// experiments. If all is true, then include all experiment flags,
+// regardless of base.
+func expList(exp, base *goexperiment.Flags, all bool) []string {
        var list []string
        rv := reflect.ValueOf(exp).Elem()
        var rBase reflect.Value
@@ -124,7 +125,7 @@ func expList(exp, base *goexperiment.Flags) []string {
                if base != nil {
                        baseVal = rBase.Field(i).Bool()
                }
-               if val != baseVal {
+               if all || val != baseVal {
                        if val {
                                list = append(list, name)
                        } else {
@@ -140,11 +141,11 @@ func expList(exp, base *goexperiment.Flags) []string {
 // GOEXPERIMENT is exactly what a user would set on the command line
 // to get the set of enabled experiments.
 func GOEXPERIMENT() string {
-       return strings.Join(expList(&Experiment, &experimentBaseline), ",")
+       return strings.Join(expList(&Experiment, &experimentBaseline, false), ",")
 }
 
 // EnabledExperiments returns a list of enabled experiments, as
 // lower-cased experiment names.
 func EnabledExperiments() []string {
-       return expList(&Experiment, nil)
+       return expList(&Experiment, nil, false)
 }
index 6a8a69116df141e0e6d0abc01e90c6bfc601cf53..9fcab4cc85b1c4a855c298e9c51c8dd90992fd29 100644 (file)
@@ -93,10 +93,16 @@ func (versionFlag) Set(s string) error {
 
        p := ""
 
-       // If the enabled experiments differ from the defaults,
-       // include that difference.
-       if goexperiment := GOEXPERIMENT(); goexperiment != "" {
-               p = " X:" + goexperiment
+       if s == "goexperiment" {
+               // test/run.go uses this to discover the full set of
+               // experiment tags. Report everything.
+               p = " X:" + strings.Join(expList(&Experiment, nil, true), ",")
+       } else {
+               // If the enabled experiments differ from the defaults,
+               // include that difference.
+               if goexperiment := GOEXPERIMENT(); goexperiment != "" {
+                       p = " X:" + goexperiment
+               }
        }
 
        // The go command invokes -V=full to get a unique identifier
index feab88338c30bf94ddebd9fcc9e5c1619111ed37..feec2b50beb2eb1349f284376bb461315fb9752a 100644 (file)
@@ -376,6 +376,7 @@ type context struct {
        GOARCH     string
        cgoEnabled bool
        noOptEnv   bool
+       expTags    map[string]bool // Set lazily
 }
 
 // shouldTest looks for build tags in a source file and returns
@@ -445,26 +446,28 @@ func (ctxt *context) match(name string) bool {
                }
        }
 
-       exp := os.Getenv("GOEXPERIMENT")
-       if exp == "" {
-               // If GOEXPERIMENT environment variable is unset, get the default value
-               // that is baked into the toolchain.
-               cmd := exec.Command(goTool(), "tool", "compile", "-V")
-               out, err := cmd.CombinedOutput()
-               if err == nil {
+       if strings.HasPrefix(name, "goexperiment.") {
+               // Query goexperiment tags from the toolchain.
+               if ctxt.expTags == nil {
+                       ctxt.expTags = make(map[string]bool)
+                       cmd := exec.Command(goTool(), "tool", "compile", "-V=goexperiment")
+                       out, err := cmd.CombinedOutput()
+                       if err != nil {
+                               log.Fatalf("failed to get GOEXPERIMENT configuration:\n%s", out)
+                       }
                        i := bytes.Index(out, []byte("X:"))
                        if i != -1 {
-                               exp = string(out[i+2:])
-                       }
-               }
-       }
-       if exp != "" {
-               experiments := strings.Split(exp, ",")
-               for _, e := range experiments {
-                       if name == "goexperiment."+e {
-                               return true
+                               for _, exp := range strings.Split(string(out[i+2:]), ",") {
+                                       v := true
+                                       if strings.HasPrefix(exp, "no") {
+                                               v, exp = false, exp[2:]
+                                       }
+                                       ctxt.expTags["goexperiment."+exp] = v
+                               }
                        }
                }
+
+               return ctxt.expTags[name]
        }
 
        if name == "cgo" && ctxt.cgoEnabled {