Manual scheduling hint; usually unnecessary and indicates deeper design issues
Flag.LowerC = runtime.GOMAXPROCS(0)
1// Copyright 2009 The Go Authors. All rights reserved.2// Use of this source code is governed by a BSD-style3// license that can be found in the LICENSE file.45package base67import (8 "cmd/internal/cov/covcmd"9 "cmd/internal/telemetry/counter"10 "encoding/json"11 "flag"12 "fmt"13 "internal/buildcfg"14 "internal/platform"15 "log"16 "os"17 "reflect"18 "runtime"19 "strings"2021 "cmd/internal/obj"22 "cmd/internal/objabi"23 "cmd/internal/sys"24)2526func usage() {27 fmt.Fprintf(os.Stderr, "usage: compile [options] file.go...\n")28 objabi.Flagprint(os.Stderr)29 Exit(2)30}3132// Flag holds the parsed command-line flags.33// See ParseFlag for non-zero defaults.34var Flag CmdFlags3536// A CountFlag is a counting integer flag.37// It accepts -name=value to set the value directly,38// but it also accepts -name with no =value to increment the count.39type CountFlag int4041// CmdFlags defines the command-line flags (see var Flag).42// Each struct field is a different flag, by default named for the lower-case of the field name.43// If the flag name is a single letter, the default flag name is left upper-case.44// If the flag name is "Lower" followed by a single letter, the default flag name is the lower-case of the last letter.45//46// If this default flag name can't be made right, the `flag` struct tag can be used to replace it,47// but this should be done only in exceptional circumstances: it helps everyone if the flag name48// is obvious from the field name when the flag is used elsewhere in the compiler sources.49// The `flag:"-"` struct tag makes a field invisible to the flag logic and should also be used sparingly.50//51// Each field must have a `help` struct tag giving the flag help message.52//53// The allowed field types are bool, int, string, pointers to those (for values stored elsewhere),54// CountFlag (for a counting flag), and func(string) (for a flag that uses special code for parsing).55type CmdFlags struct {56 // Single letters57 B CountFlag "help:\"disable bounds checking\""58 C CountFlag "help:\"disable printing of columns in error messages\""59 D string "help:\"set relative `path` for local imports\""60 E CountFlag "help:\"debug symbol export\""61 I func(string) "help:\"add `directory` to import search path\""62 K CountFlag "help:\"debug missing line numbers\""63 L CountFlag "help:\"also show actual source file names in error messages for positions affected by //line directives\""64 N CountFlag "help:\"disable optimizations\""65 S CountFlag "help:\"print assembly listing\""66 // V is added by objabi.AddVersionFlag67 W CountFlag "help:\"debug parse tree after type checking\""6869 LowerC int "help:\"concurrency during compilation (1 means no concurrency)\""70 LowerD flag.Value "help:\"enable debugging settings; try -d help\""71 LowerE CountFlag "help:\"no limit on number of errors reported\""72 LowerH CountFlag "help:\"halt on error\""73 LowerJ CountFlag "help:\"debug runtime-initialized variables\""74 LowerL CountFlag "help:\"disable inlining\""75 LowerM CountFlag "help:\"print optimization decisions\""76 LowerO string "help:\"write output to `file`\""77 LowerP *string "help:\"set expected package import `path`\"" // &Ctxt.Pkgpath, set below78 LowerR CountFlag "help:\"debug generated wrappers\""79 LowerT bool "help:\"enable tracing for debugging the compiler\""80 LowerW CountFlag "help:\"debug type checking\""81 LowerU CountFlag "help:\"emit unsorted warnings/errors\""82 LowerV *bool "help:\"increase debug verbosity\""8384 // Special characters85 Percent CountFlag "flag:\"%\" help:\"debug non-static initializers\""86 CompilingRuntime bool "flag:\"+\" help:\"compiling runtime\""8788 // Longer names89 AsmHdr string "help:\"write assembly header to `file`\""90 ASan bool "help:\"build code compatible with C/C++ address sanitizer\""91 Bench string "help:\"append benchmark times to `file`\""92 BlockProfile string "help:\"write block profile to `file`\""93 BuildID string "help:\"record `id` as the build id in the export metadata\""94 CPUProfile string "help:\"write cpu profile to `file`\""95 Complete bool "help:\"compiling complete package (no C or assembly)\""96 ClobberDead bool "help:\"clobber dead stack slots (for debugging)\""97 ClobberDeadReg bool "help:\"clobber dead registers (for debugging)\""98 Dwarf bool "help:\"generate DWARF symbols\""99 DwarfBASEntries *bool "help:\"use base address selection entries in DWARF\"" // &Ctxt.UseBASEntries, set below100 DwarfLocationLists *bool "help:\"add location lists to DWARF in optimized mode\"" // &Ctxt.Flag_locationlists, set below101 Dynlink *bool "help:\"support references to Go symbols defined in other shared libraries\"" // &Ctxt.Flag_dynlink, set below102 EmbedCfg func(string) "help:\"read go:embed configuration from `file`\""103 Env func(string) "help:\"add `definition` of the form key=value to environment\""104 GenDwarfInl int "help:\"generate DWARF inline info records\"" // 0=disabled, 1=funcs, 2=funcs+formals/locals105 GoVersion string "help:\"required version of the runtime\""106 ImportCfg func(string) "help:\"read import configuration from `file`\""107 InstallSuffix string "help:\"set pkg directory `suffix`\""108 JSON string "help:\"version,file for JSON compiler/optimizer detail output\""109 Lang string "help:\"Go language version source code expects\""110 LinkObj string "help:\"write linker-specific object to `file`\""111 LinkShared *bool "help:\"generate code that will be linked against Go shared libraries\"" // &Ctxt.Flag_linkshared, set below112 Live CountFlag "help:\"debug liveness analysis\""113 MSan bool "help:\"build code compatible with C/C++ memory sanitizer\""114 MemProfile string "help:\"write memory profile to `file`\""115 MemProfileRate int "help:\"set runtime.MemProfileRate to `rate`\""116 MutexProfile string "help:\"write mutex profile to `file`\""117 NoLocalImports bool "help:\"reject local (relative) imports\""118 CoverageCfg func(string) "help:\"read coverage configuration from `file`\""119 Pack bool "help:\"write to file.a instead of file.o\""120 Race bool "help:\"enable race detector\""121 Shared *bool "help:\"generate code that can be linked into a shared library\"" // &Ctxt.Flag_shared, set below122 SmallFrames bool "help:\"reduce the size limit for stack allocated objects\"" // small stacks, to diagnose GC latency; see golang.org/issue/27732123 Spectre string "help:\"enable spectre mitigations in `list` (all, index, ret)\""124 Std bool "help:\"compiling standard library\""125 SymABIs string "help:\"read symbol ABIs from `file`\""126 TraceProfile string "help:\"write an execution trace to `file`\""127 TrimPath string "help:\"remove `prefix` from recorded source file paths\""128 WB bool "help:\"enable write barrier\"" // TODO: remove129 PgoProfile string "help:\"read profile or pre-process profile from `file`\""130 ErrorURL bool "help:\"print explanatory URL with error message if applicable\""131132 // Configuration derived from flags; not a flag itself.133 Cfg struct {134 Embed struct { // set by -embedcfg135 Patterns map[string][]string136 Files map[string]string137 }138 ImportDirs []string // appended to by -I139 ImportMap map[string]string // set by -importcfg140 PackageFile map[string]string // set by -importcfg; nil means not in use141 CoverageInfo *covcmd.CoverFixupConfig // set by -coveragecfg142 SpectreIndex bool // set by -spectre=index or -spectre=all143 // Whether we are adding any sort of code instrumentation, such as144 // when the race detector is enabled.145 Instrumenting bool146 }147}148149func addEnv(s string) {150 i := strings.Index(s, "=")151 if i < 0 {152 log.Fatal("-env argument must be of the form key=value")153 }154 os.Setenv(s[:i], s[i+1:])155}156157// ParseFlags parses the command-line flags into Flag.158func ParseFlags() {159 Flag.I = addImportDir160161 Flag.LowerC = runtime.GOMAXPROCS(0)162 Flag.LowerD = objabi.NewDebugFlag(&Debug, DebugSSA)163 Flag.LowerP = &Ctxt.Pkgpath164 Flag.LowerV = &Ctxt.Debugvlog165166 Flag.Dwarf = buildcfg.GOARCH != "wasm"167 Flag.DwarfBASEntries = &Ctxt.UseBASEntries168 Flag.DwarfLocationLists = &Ctxt.Flag_locationlists169 *Flag.DwarfLocationLists = true170 Flag.Dynlink = &Ctxt.Flag_dynlink171 Flag.EmbedCfg = readEmbedCfg172 Flag.Env = addEnv173 Flag.GenDwarfInl = 2174 Flag.ImportCfg = readImportCfg175 Flag.CoverageCfg = readCoverageCfg176 Flag.LinkShared = &Ctxt.Flag_linkshared177 Flag.Shared = &Ctxt.Flag_shared178 Flag.WB = true179180 Debug.ConcurrentOk = true181 Debug.CompressInstructions = 1182 Debug.MaxShapeLen = 500183 Debug.AlignHot = 1184 Debug.InlFuncsWithClosures = 1185 Debug.InlStaticInit = 1186 Debug.FreeAppend = 1187 Debug.PGOInline = 1188 Debug.PGODevirtualize = 2189 Debug.SyncFrames = -1 // disable sync markers by default190 Debug.VariableMakeThreshold = 32 // 32 byte default for stack allocated make results191 Debug.ZeroCopy = 1192 Debug.RangeFuncCheck = 1193 Debug.MergeLocals = 1194 Debug.RewriteResults = 1195196 Debug.Checkptr = -1 // so we can tell whether it is set explicitly197198 Flag.Cfg.ImportMap = make(map[string]string)199200 objabi.AddVersionFlag() // -V201 registerFlags()202 objabi.Flagparse(usage)203 counter.CountFlags("compile/flag:", *flag.CommandLine)204205 if gcd := os.Getenv("GOCOMPILEDEBUG"); gcd != "" {206 // This will only override the flags set in gcd;207 // any others set on the command line remain set.208 Flag.LowerD.Set(gcd)209 }210211 if Debug.Gossahash != "" {212 hashDebug = NewHashDebug("gossahash", Debug.Gossahash, nil)213 }214 obj.SetFIPSDebugHash(Debug.FIPSHash)215216 // Compute whether we're compiling the runtime from the package path. Test217 // code can also use the flag to set this explicitly.218 if Flag.Std && objabi.LookupPkgSpecial(Ctxt.Pkgpath).Runtime {219 Flag.CompilingRuntime = true220 }221222 Ctxt.Std = Flag.Std223224 // Three inputs govern loop iteration variable rewriting, hash, experiment, flag.225 // The loop variable rewriting is:226 // IF non-empty hash, then hash determines behavior (function+line match) (*)227 // ELSE IF experiment and flag==0, then experiment (set flag=1)228 // ELSE flag (note that build sets flag per-package), with behaviors:229 // -1 => no change to behavior.230 // 0 => no change to behavior (unless non-empty hash, see above)231 // 1 => apply change to likely-iteration-variable-escaping loops232 // 2 => apply change, log results233 // 11 => apply change EVERYWHERE, do not log results (for debugging/benchmarking)234 // 12 => apply change EVERYWHERE, log results (for debugging/benchmarking)235 //236 // The expected uses of the these inputs are, in believed most-likely to least likely:237 // GOEXPERIMENT=loopvar -- apply change to entire application238 // -gcflags=some_package=-d=loopvar=1 -- apply change to some_package (**)239 // -gcflags=some_package=-d=loopvar=2 -- apply change to some_package, log it240 // GOEXPERIMENT=loopvar -gcflags=some_package=-d=loopvar=-1 -- apply change to all but one package241 // GOCOMPILEDEBUG=loopvarhash=... -- search for failure cause242 //243 // (*) For debugging purposes, providing loopvar flag >= 11 will expand the hash-eligible set of loops to all.244 // (**) Loop semantics, changed or not, follow code from a package when it is inlined; that is, the behavior245 // of an application compiled with partially modified loop semantics does not depend on inlining.246247 if Debug.LoopVarHash != "" {248 // This first little bit controls the inputs for debug-hash-matching.249 mostInlineOnly := true250 if strings.HasPrefix(Debug.LoopVarHash, "IL") {251 // When hash-searching on a position that is an inline site, default is to use the252 // most-inlined position only. This makes the hash faster, plus there's no point253 // reporting a problem with all the inlining; there's only one copy of the source.254 // However, if for some reason you wanted it per-site, you can get this. (The default255 // hash-search behavior for compiler debugging is at an inline site.)256 Debug.LoopVarHash = Debug.LoopVarHash[2:]257 mostInlineOnly = false258 }259 // end of testing trickiness260 LoopVarHash = NewHashDebug("loopvarhash", Debug.LoopVarHash, nil)261 if Debug.LoopVar < 11 { // >= 11 means all loops are rewrite-eligible262 Debug.LoopVar = 1 // 1 means those loops that syntactically escape their dcl vars are eligible.263 }264 LoopVarHash.SetInlineSuffixOnly(mostInlineOnly)265 } else if buildcfg.Experiment.LoopVar && Debug.LoopVar == 0 {266 Debug.LoopVar = 1267 }268269 if Debug.Converthash != "" {270 ConvertHash = NewHashDebug("converthash", Debug.Converthash, nil)271 } else {272 // quietly disable the convert hash changes273 ConvertHash = NewHashDebug("converthash", "qn", nil)274 }275 if Debug.Fmahash != "" {276 FmaHash = NewHashDebug("fmahash", Debug.Fmahash, nil)277 }278 if Debug.PGOHash != "" {279 PGOHash = NewHashDebug("pgohash", Debug.PGOHash, nil)280 }281 if Debug.LiteralAllocHash != "" {282 LiteralAllocHash = NewHashDebug("literalalloc", Debug.LiteralAllocHash, nil)283 }284285 if Debug.MergeLocalsHash != "" {286 MergeLocalsHash = NewHashDebug("mergelocals", Debug.MergeLocalsHash, nil)287 }288 if Debug.VariableMakeHash != "" {289 VariableMakeHash = NewHashDebug("variablemake", Debug.VariableMakeHash, nil)290 }291292 if Flag.MSan && !platform.MSanSupported(buildcfg.GOOS, buildcfg.GOARCH) {293 log.Fatalf("%s/%s does not support -msan", buildcfg.GOOS, buildcfg.GOARCH)294 }295 if Flag.ASan && !platform.ASanSupported(buildcfg.GOOS, buildcfg.GOARCH) {296 log.Fatalf("%s/%s does not support -asan", buildcfg.GOOS, buildcfg.GOARCH)297 }298 if Flag.Race && !platform.RaceDetectorSupported(buildcfg.GOOS, buildcfg.GOARCH) {299 log.Fatalf("%s/%s does not support -race", buildcfg.GOOS, buildcfg.GOARCH)300 }301 if (*Flag.Shared || *Flag.Dynlink || *Flag.LinkShared) && !Ctxt.Arch.InFamily(sys.AMD64, sys.ARM, sys.ARM64, sys.I386, sys.Loong64, sys.MIPS64, sys.PPC64, sys.RISCV64, sys.S390X) {302 log.Fatalf("%s/%s does not support -shared", buildcfg.GOOS, buildcfg.GOARCH)303 }304 parseSpectre(Flag.Spectre) // left as string for RecordFlags305306 Ctxt.CompressInstructions = Debug.CompressInstructions != 0307 Ctxt.Flag_shared = Ctxt.Flag_dynlink || Ctxt.Flag_shared308 Ctxt.Flag_optimize = Flag.N == 0309 Ctxt.Debugasm = int(Flag.S)310 Ctxt.Flag_maymorestack = Debug.MayMoreStack311 Ctxt.Flag_noRefName = Debug.NoRefName != 0312313 if flag.NArg() < 1 {314 usage()315 }316317 if Flag.GoVersion != "" && Flag.GoVersion != runtime.Version() {318 fmt.Printf("compile: version %q does not match go tool version %q\n", runtime.Version(), Flag.GoVersion)319 Exit(2)320 }321322 if *Flag.LowerP == "" {323 *Flag.LowerP = obj.UnlinkablePkg324 }325326 if Flag.LowerO == "" {327 p := flag.Arg(0)328 if i := strings.LastIndex(p, "/"); i >= 0 {329 p = p[i+1:]330 }331 if runtime.GOOS == "windows" {332 if i := strings.LastIndex(p, `\`); i >= 0 {333 p = p[i+1:]334 }335 }336 if i := strings.LastIndex(p, "."); i >= 0 {337 p = p[:i]338 }339 suffix := ".o"340 if Flag.Pack {341 suffix = ".a"342 }343 Flag.LowerO = p + suffix344 }345 switch {346 case Flag.Race && Flag.MSan:347 log.Fatal("cannot use both -race and -msan")348 case Flag.Race && Flag.ASan:349 log.Fatal("cannot use both -race and -asan")350 case Flag.MSan && Flag.ASan:351 log.Fatal("cannot use both -msan and -asan")352 }353 if Flag.Race || Flag.MSan || Flag.ASan {354 // -race, -msan and -asan imply -d=checkptr for now.355 if Debug.Checkptr == -1 { // if not set explicitly356 Debug.Checkptr = 1357 }358 }359360 if Flag.LowerC < 1 {361 log.Fatalf("-c must be at least 1, got %d", Flag.LowerC)362 }363 if !concurrentBackendAllowed() {364 Flag.LowerC = 1365 }366367 if Flag.CompilingRuntime {368 // It is not possible to build the runtime with no optimizations,369 // because the compiler cannot eliminate enough write barriers.370 Flag.N = 0371 Ctxt.Flag_optimize = true372373 // Runtime can't use -d=checkptr, at least not yet.374 Debug.Checkptr = 0375376 // Fuzzing the runtime isn't interesting either.377 Debug.Libfuzzer = 0378 }379380 if len(Flag.Cfg.ImportDirs) > 0 && Flag.Cfg.PackageFile != nil {381 log.Fatalf("cannot use both -I and -importcfg")382 }383384 if Debug.Checkptr == -1 { // if not set explicitly385 Debug.Checkptr = 0386 }387388 // set via a -d flag389 Ctxt.Debugpcln = Debug.PCTab390391 // https://golang.org/issue/67502392 if buildcfg.GOOS == "plan9" && buildcfg.GOARCH == "386" {393 Debug.AlignHot = 0394 }395}396397// registerFlags adds flag registrations for all the fields in Flag.398// See the comment on type CmdFlags for the rules.399func registerFlags() {400 var (401 boolType = reflect.TypeFor[bool]()402 intType = reflect.TypeFor[int]()403 stringType = reflect.TypeFor[string]()404 ptrBoolType = reflect.TypeFor[*bool]()405 ptrIntType = reflect.TypeFor[*int]()406 ptrStringType = reflect.TypeFor[*string]()407 countType = reflect.TypeFor[CountFlag]()408 funcType = reflect.TypeFor[func(string)]()409 )410411 v := reflect.ValueOf(&Flag).Elem()412 t := v.Type()413 for i := 0; i < t.NumField(); i++ {414 f := t.Field(i)415 if f.Name == "Cfg" {416 continue417 }418419 var name string420 if len(f.Name) == 1 {421 name = f.Name422 } else if len(f.Name) == 6 && f.Name[:5] == "Lower" && 'A' <= f.Name[5] && f.Name[5] <= 'Z' {423 name = string(rune(f.Name[5] + 'a' - 'A'))424 } else {425 name = strings.ToLower(f.Name)426 }427 if tag := f.Tag.Get("flag"); tag != "" {428 name = tag429 }430431 help := f.Tag.Get("help")432 if help == "" {433 panic(fmt.Sprintf("base.Flag.%s is missing help text", f.Name))434 }435436 if k := f.Type.Kind(); (k == reflect.Ptr || k == reflect.Func) && v.Field(i).IsNil() {437 panic(fmt.Sprintf("base.Flag.%s is uninitialized %v", f.Name, f.Type))438 }439440 switch f.Type {441 case boolType:442 p := v.Field(i).Addr().Interface().(*bool)443 flag.BoolVar(p, name, *p, help)444 case intType:445 p := v.Field(i).Addr().Interface().(*int)446 flag.IntVar(p, name, *p, help)447 case stringType:448 p := v.Field(i).Addr().Interface().(*string)449 flag.StringVar(p, name, *p, help)450 case ptrBoolType:451 p := v.Field(i).Interface().(*bool)452 flag.BoolVar(p, name, *p, help)453 case ptrIntType:454 p := v.Field(i).Interface().(*int)455 flag.IntVar(p, name, *p, help)456 case ptrStringType:457 p := v.Field(i).Interface().(*string)458 flag.StringVar(p, name, *p, help)459 case countType:460 p := (*int)(v.Field(i).Addr().Interface().(*CountFlag))461 objabi.Flagcount(name, help, p)462 case funcType:463 f := v.Field(i).Interface().(func(string))464 objabi.Flagfn1(name, help, f)465 default:466 if val, ok := v.Field(i).Interface().(flag.Value); ok {467 flag.Var(val, name, help)468 } else {469 panic(fmt.Sprintf("base.Flag.%s has unexpected type %s", f.Name, f.Type))470 }471 }472 }473}474475// concurrentFlagOk reports whether the current compiler flags476// are compatible with concurrent compilation.477func concurrentFlagOk() bool {478 // TODO(rsc): Many of these are fine. Remove them.479 return Flag.Percent == 0 &&480 Flag.E == 0 &&481 Flag.K == 0 &&482 Flag.L == 0 &&483 Flag.LowerJ == 0 &&484 Flag.LowerM == 0 &&485 Flag.LowerR == 0486}487488func concurrentBackendAllowed() bool {489 if !concurrentFlagOk() {490 return false491 }492493 // Debug.S by itself is ok, because all printing occurs494 // while writing the object file, and that is non-concurrent.495 // Adding Debug_vlog, however, causes Debug.S to also print496 // while flushing the plist, which happens concurrently.497 if Ctxt.Debugvlog || !Debug.ConcurrentOk || Flag.Live > 0 {498 return false499 }500 // TODO: Test and delete this condition.501 if buildcfg.Experiment.FieldTrack {502 return false503 }504 // TODO: fix races and enable the following flags505 if Ctxt.Flag_dynlink || Flag.Race {506 return false507 }508 return true509}510511func addImportDir(dir string) {512 if dir != "" {513 Flag.Cfg.ImportDirs = append(Flag.Cfg.ImportDirs, dir)514 }515}516517func readImportCfg(file string) {518 if Flag.Cfg.ImportMap == nil {519 Flag.Cfg.ImportMap = make(map[string]string)520 }521 Flag.Cfg.PackageFile = map[string]string{}522 data, err := os.ReadFile(file)523 if err != nil {524 log.Fatalf("-importcfg: %v", err)525 }526527 for lineNum, line := range strings.Split(string(data), "\n") {528 lineNum++ // 1-based529 line = strings.TrimSpace(line)530 if line == "" || strings.HasPrefix(line, "#") {531 continue532 }533534 verb, args, found := strings.Cut(line, " ")535 if found {536 args = strings.TrimSpace(args)537 }538 before, after, hasEq := strings.Cut(args, "=")539540 switch verb {541 default:542 log.Fatalf("%s:%d: unknown directive %q", file, lineNum, verb)543 case "importmap":544 if !hasEq || before == "" || after == "" {545 log.Fatalf(`%s:%d: invalid importmap: syntax is "importmap old=new"`, file, lineNum)546 }547 Flag.Cfg.ImportMap[before] = after548 case "packagefile":549 if !hasEq || before == "" || after == "" {550 log.Fatalf(`%s:%d: invalid packagefile: syntax is "packagefile path=filename"`, file, lineNum)551 }552 Flag.Cfg.PackageFile[before] = after553 }554 }555}556557func readCoverageCfg(file string) {558 var cfg covcmd.CoverFixupConfig559 data, err := os.ReadFile(file)560 if err != nil {561 log.Fatalf("-coveragecfg: %v", err)562 }563 if err := json.Unmarshal(data, &cfg); err != nil {564 log.Fatalf("error reading -coveragecfg file %q: %v", file, err)565 }566 Flag.Cfg.CoverageInfo = &cfg567}568569func readEmbedCfg(file string) {570 data, err := os.ReadFile(file)571 if err != nil {572 log.Fatalf("-embedcfg: %v", err)573 }574 if err := json.Unmarshal(data, &Flag.Cfg.Embed); err != nil {575 log.Fatalf("%s: %v", file, err)576 }577 if Flag.Cfg.Embed.Patterns == nil {578 log.Fatalf("%s: invalid embedcfg: missing Patterns", file)579 }580 if Flag.Cfg.Embed.Files == nil {581 log.Fatalf("%s: invalid embedcfg: missing Files", file)582 }583}584585// parseSpectre parses the spectre configuration from the string s.586func parseSpectre(s string) {587 for f := range strings.SplitSeq(s, ",") {588 f = strings.TrimSpace(f)589 switch f {590 default:591 log.Fatalf("unknown setting -spectre=%s", f)592 case "":593 // nothing594 case "all":595 Flag.Cfg.SpectreIndex = true596 Ctxt.Retpoline = true597 case "index":598 Flag.Cfg.SpectreIndex = true599 case "ret":600 Ctxt.Retpoline = true601 }602 }603604 if Flag.Cfg.SpectreIndex {605 switch buildcfg.GOARCH {606 case "amd64":607 // ok608 default:609 log.Fatalf("GOARCH=%s does not support -spectre=index", buildcfg.GOARCH)610 }611 }612}
Same data, no extra tab — call code_get_file + code_get_findings over MCP from Claude/Cursor/Copilot.