Skip to content

Commit

Permalink
Merge commit '0f7b7600fbf2bda2da9fde3d538b17d9cd39f11d' into tailscal…
Browse files Browse the repository at this point in the history
…e.go1.24
  • Loading branch information
bradfitz committed Feb 20, 2025
2 parents c1d3e9e + 0f7b760 commit 7c08383
Show file tree
Hide file tree
Showing 9 changed files with 136 additions and 10 deletions.
11 changes: 11 additions & 0 deletions doc/godebug.md
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,17 @@ and the [go command documentation](/cmd/go#hdr-Build_and_test_caching).

### Go 1.24

Go 1.24 added a new `fips140` setting that controls whether the Go
Cryptographic Module operates in FIPS 140-3 mode.
The possible values are:
- "off": no special support for FIPS 140-3 mode. This is the default.
- "on": the Go Cryptographic Module operates in FIPS 140-3 mode.
- "only": like "on", but cryptographic algorithms not approved by
FIPS 140-3 return an error or panic.
For more information, see [FIPS 140-3 Compliance](/doc/security/fips140).
This setting is fixed at program startup time, and can't be modified
by changing the `GODEBUG` environment variable after the program starts.

Go 1.24 changed the global [`math/rand.Seed`](/pkg/math/rand/#Seed) to be a
no-op. This behavior is controlled by the `randseednop` setting.
For Go 1.24 it defaults to `randseednop=1`.
Expand Down
32 changes: 32 additions & 0 deletions src/cmd/compile/internal/inline/inl.go
Original file line number Diff line number Diff line change
Expand Up @@ -1009,6 +1009,38 @@ func canInlineCallExpr(callerfn *ir.Func, n *ir.CallExpr, callee *ir.Func, bigCa
return false, 0, false
}

isClosureParent := func(closure, parent *ir.Func) bool {
for p := closure.ClosureParent; p != nil; p = p.ClosureParent {
if p == parent {
return true
}
}
return false
}
if isClosureParent(callerfn, callee) {
// Can't recursively inline a parent of the closure into itself.
if log && logopt.Enabled() {
logopt.LogOpt(n.Pos(), "cannotInlineCall", "inline", fmt.Sprintf("recursive call to closure parent: %s, %s", ir.FuncName(callerfn), ir.FuncName(callee)))
}
return false, 0, false
}
if isClosureParent(callee, callerfn) {
// Can't recursively inline a closure if there's a call to the parent in closure body.
if ir.Any(callee, func(node ir.Node) bool {
if call, ok := node.(*ir.CallExpr); ok {
if name, ok := call.Fun.(*ir.Name); ok && isClosureParent(callerfn, name.Func) {
return true
}
}
return false
}) {
if log && logopt.Enabled() {
logopt.LogOpt(n.Pos(), "cannotInlineCall", "inline", fmt.Sprintf("recursive call to closure parent: %s, %s", ir.FuncName(callerfn), ir.FuncName(callee)))
}
return false, 0, false
}
}

if base.Flag.Cfg.Instrumenting && types.IsNoInstrumentPkg(callee.Sym().Pkg) {
// Runtime package must not be instrumented.
// Instrument skips runtime package. However, some runtime code can be
Expand Down
11 changes: 11 additions & 0 deletions src/os/os_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3848,3 +3848,14 @@ func TestRemoveReadOnlyFile(t *testing.T) {
}
})
}

func TestOpenFileDevNull(t *testing.T) {
// See https://go.dev/issue/71752.
t.Parallel()

f, err := OpenFile(DevNull, O_WRONLY|O_CREATE|O_TRUNC, 0o644)
if err != nil {
t.Fatalf("OpenFile(DevNull): %v", err)
}
f.Close()
}
10 changes: 10 additions & 0 deletions src/runtime/stubs.go
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,16 @@ func asmcgocall(fn, arg unsafe.Pointer) int32

func morestack()

// morestack_noctxt should be an internal detail,
// but widely used packages access it using linkname.
// Notable members of the hall of shame include:
// - github.com/bytedance/sonic
//
// Do not remove or change the type signature.
// See go.dev/issues/67401.
// See go.dev/issues/71672.
//
//go:linkname morestack_noctxt
func morestack_noctxt()

func rt0_go()
Expand Down
23 changes: 22 additions & 1 deletion src/runtime/symtab.go
Original file line number Diff line number Diff line change
Expand Up @@ -480,7 +480,18 @@ var pinnedTypemaps []map[typeOff]*_type
// the relocated one.
var aixStaticDataBase uintptr // linker symbol

var firstmoduledata moduledata // linker symbol
var firstmoduledata moduledata // linker symbol

// lastmoduledatap should be an internal detail,
// but widely used packages access it using linkname.
// Notable members of the hall of shame include:
// - github.com/bytedance/sonic
//
// Do not remove or change the type signature.
// See go.dev/issues/67401.
// See go.dev/issues/71672.
//
//go:linkname lastmoduledatap
var lastmoduledatap *moduledata // linker symbol

var modulesSlice *[]*moduledata // see activeModules
Expand Down Expand Up @@ -591,6 +602,16 @@ func moduledataverify() {

const debugPcln = false

// moduledataverify1 should be an internal detail,
// but widely used packages access it using linkname.
// Notable members of the hall of shame include:
// - github.com/bytedance/sonic
//
// Do not remove or change the type signature.
// See go.dev/issues/67401.
// See go.dev/issues/71672.
//
//go:linkname moduledataverify1
func moduledataverify1(datap *moduledata) {
// Check that the pclntab's format is valid.
hdr := datap.pcHeader
Expand Down
5 changes: 3 additions & 2 deletions src/runtime/sys_linux_s390x.s
Original file line number Diff line number Diff line change
Expand Up @@ -112,9 +112,10 @@ TEXT runtime·usleep(SB),NOSPLIT,$16-4
MOVW $1000000, R3
DIVD R3, R2
MOVD R2, 8(R15)
MOVW $1000, R3
MULLD R2, R3
MULLD R2, R3 // Convert sec to usec and subtract
SUB R3, R4
MOVW $1000, R3
MULLD R3, R4 // Convert remaining usec into nsec.
MOVD R4, 16(R15)

// nanosleep(&ts, 0)
Expand Down
22 changes: 17 additions & 5 deletions src/syscall/syscall_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ func NewCallbackCDecl(fn any) uintptr {
//sys GetVersion() (ver uint32, err error)
//sys formatMessage(flags uint32, msgsrc uintptr, msgid uint32, langid uint32, buf []uint16, args *byte) (n uint32, err error) = FormatMessageW
//sys ExitProcess(exitcode uint32)
//sys CreateFile(name *uint16, access uint32, mode uint32, sa *SecurityAttributes, createmode uint32, attrs uint32, templatefile int32) (handle Handle, err error) [failretval==InvalidHandle] = CreateFileW
//sys createFile(name *uint16, access uint32, mode uint32, sa *SecurityAttributes, createmode uint32, attrs uint32, templatefile int32) (handle Handle, err error) [failretval == InvalidHandle || e1 == ERROR_ALREADY_EXISTS ] = CreateFileW
//sys readFile(handle Handle, buf []byte, done *uint32, overlapped *Overlapped) (err error) = ReadFile
//sys writeFile(handle Handle, buf []byte, done *uint32, overlapped *Overlapped) (err error) = WriteFile
//sys SetFilePointer(handle Handle, lowoffset int32, highoffsetptr *int32, whence uint32) (newlowoffset uint32, err error) [failretval==0xffffffff]
Expand Down Expand Up @@ -404,18 +404,20 @@ func Open(name string, flag int, perm uint32) (fd Handle, err error) {
const _FILE_FLAG_WRITE_THROUGH = 0x80000000
attrs |= _FILE_FLAG_WRITE_THROUGH
}
h, err := CreateFile(namep, access, sharemode, sa, createmode, attrs, 0)
if err != nil {
h, err := createFile(namep, access, sharemode, sa, createmode, attrs, 0)
if h == InvalidHandle {
if err == ERROR_ACCESS_DENIED && (flag&O_WRONLY != 0 || flag&O_RDWR != 0) {
// We should return EISDIR when we are trying to open a directory with write access.
fa, e1 := GetFileAttributes(namep)
if e1 == nil && fa&FILE_ATTRIBUTE_DIRECTORY != 0 {
err = EISDIR
}
}
return InvalidHandle, err
return h, err
}
if flag&O_TRUNC == O_TRUNC {
// Ignore O_TRUNC if the file has just been created.
if flag&O_TRUNC == O_TRUNC &&
(createmode == OPEN_EXISTING || (createmode == OPEN_ALWAYS && err == ERROR_ALREADY_EXISTS)) {
err = Ftruncate(h, 0)
if err != nil {
CloseHandle(h)
Expand Down Expand Up @@ -1454,3 +1456,13 @@ func GetStartupInfo(startupInfo *StartupInfo) error {
getStartupInfo(startupInfo)
return nil
}

func CreateFile(name *uint16, access uint32, mode uint32, sa *SecurityAttributes, createmode uint32, attrs uint32, templatefile int32) (handle Handle, err error) {
handle, err = createFile(name, access, mode, sa, createmode, attrs, templatefile)
if handle != InvalidHandle {
// CreateFileW can return ERROR_ALREADY_EXISTS with a valid handle.
// We only want to return an error if the handle is invalid.
err = nil
}
return handle, err
}
4 changes: 2 additions & 2 deletions src/syscall/zsyscall_windows.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

28 changes: 28 additions & 0 deletions test/fixedbugs/issue71680.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// compile

// Copyright 2025 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 p

type Parser struct{}
type Node struct{}

type parserState func(p *Parser) parserState

func parserStateData(root *Node) parserState {
return func(p *Parser) parserState {
return parserStateOpenMap(root)(p)
}
}

func parserStateOpenMap(root *Node) parserState {
return func(p *Parser) parserState {
switch {
case p != nil:
return parserStateData(root)(p)
}
return parserStateOpenMap(root)(p)
}
}

0 comments on commit 7c08383

Please sign in to comment.