Initial commit: Go 1.23 release state

This commit is contained in:
Vorapol Rinsatitnon
2024-09-21 23:49:08 +10:00
commit 17cd57a668
13231 changed files with 3114330 additions and 0 deletions

75
doc/README.md Normal file
View File

@@ -0,0 +1,75 @@
# Release Notes
The `initial` and `next` subdirectories of this directory are for release notes.
## For developers
Release notes should be added to `next` by editing existing files or creating
new files. **Do not add RELNOTE=yes comments in CLs.** Instead, add a file to
the CL (or ask the author to do so).
At the end of the development cycle, the files will be merged by being
concatenated in sorted order by pathname. Files in the directory matching the
glob "*stdlib/*minor" are treated specially. They should be in subdirectories
corresponding to standard library package paths, and headings for those package
paths will be generated automatically.
Files in this repo's `api/next` directory must have corresponding files in
`doc/next/*stdlib/*minor`.
The files should be in the subdirectory for the package with the new
API, and should be named after the issue number of the API proposal.
For example, if the directory `6-stdlib/99-minor` is present,
then an `api/next` file with the line
pkg net/http, function F #12345
should have a corresponding file named `doc/next/6-stdlib/99-minor/net/http/12345.md`.
At a minimum, that file should contain either a full sentence or a TODO,
ideally referring to a person with the responsibility to complete the note.
If your CL addresses an accepted proposal, mention the proposal issue number in
your release note in the form `/issue/NUMBER`. A link to the issue in the text
will have this form (see below). If you don't want to mention the issue in the
text, add it as a comment:
```
<!-- go.dev/issue/12345 -->
```
If an accepted proposal is mentioned in a CL but not in the release notes, it will be
flagged as a TODO by the automated tooling. That is true even for proposals that add API.
Use the following forms in your markdown:
[http.Request] # symbol documentation; auto-linked as in Go doc strings
[Request] # short form, for symbols in the package being documented
[net/http] # package link
[#12345](/issue/12345) # GitHub issues
[CL 6789](/cl/6789) # Gerrit changelists
To preview `next` content in merged form using a local instance of the website, run:
```
go run golang.org/x/website/cmd/golangorg@latest -goroot=..
```
Then open http://localhost:6060/doc/next. Refresh the page to see your latest edits.
## For the release team
The `relnote` tool, at `golang.org/x/build/cmd/relnote`, operates on the files
in `doc/next`.
As a release cycle nears completion, run `relnote todo` to get a list of
unfinished release note work.
To prepare the release notes for a release, run `relnote generate`.
That will merge the `.md` files in `next` into a single file.
Atomically (as close to it as possible) add that file to `_content/doc` directory
of the website repository and remove the `doc/next` directory in this repository.
To begin the next release development cycle, populate the contents of `next`
with those of `initial`. From the repo root:
> cd doc
> cp -r initial/* next
Then edit `next/1-intro.md` to refer to the next version.

1073
doc/asm.html Normal file

File diff suppressed because it is too large Load Diff

6864
doc/go1.17_spec.html Normal file

File diff suppressed because it is too large Load Diff

977
doc/go_mem.html Normal file
View File

@@ -0,0 +1,977 @@
<!--{
"Title": "The Go Memory Model",
"Subtitle": "Version of June 6, 2022",
"Path": "/ref/mem"
}-->
<style>
p.rule {
font-style: italic;
}
</style>
<h2 id="introduction">Introduction</h2>
<p>
The Go memory model specifies the conditions under which
reads of a variable in one goroutine can be guaranteed to
observe values produced by writes to the same variable in a different goroutine.
</p>
<h3 id="advice">Advice</h3>
<p>
Programs that modify data being simultaneously accessed by multiple goroutines
must serialize such access.
</p>
<p>
To serialize access, protect the data with channel operations or other synchronization primitives
such as those in the <a href="/pkg/sync/"><code>sync</code></a>
and <a href="/pkg/sync/atomic/"><code>sync/atomic</code></a> packages.
</p>
<p>
If you must read the rest of this document to understand the behavior of your program,
you are being too clever.
</p>
<p>
Don't be clever.
</p>
<h3 id="overview">Informal Overview</h3>
<p>
Go approaches its memory model in much the same way as the rest of the language,
aiming to keep the semantics simple, understandable, and useful.
This section gives a general overview of the approach and should suffice for most programmers.
The memory model is specified more formally in the next section.
</p>
<p>
A <em>data race</em> is defined as
a write to a memory location happening concurrently with another read or write to that same location,
unless all the accesses involved are atomic data accesses as provided by the <code>sync/atomic</code> package.
As noted already, programmers are strongly encouraged to use appropriate synchronization
to avoid data races.
In the absence of data races, Go programs behave as if all the goroutines
were multiplexed onto a single processor.
This property is sometimes referred to as DRF-SC: data-race-free programs
execute in a sequentially consistent manner.
</p>
<p>
While programmers should write Go programs without data races,
there are limitations to what a Go implementation can do in response to a data race.
An implementation may always react to a data race by reporting the race and terminating the program.
Otherwise, each read of a single-word-sized or sub-word-sized memory location
must observe a value actually written to that location (perhaps by a concurrent executing goroutine)
and not yet overwritten.
These implementation constraints make Go more like Java or JavaScript,
in that most races have a limited number of outcomes,
and less like C and C++, where the meaning of any program with a race
is entirely undefined, and the compiler may do anything at all.
Go's approach aims to make errant programs more reliable and easier to debug,
while still insisting that races are errors and that tools can diagnose and report them.
</p>
<h2 id="model">Memory Model</h2>
<p>
The following formal definition of Go's memory model closely follows
the approach presented by Hans-J. Boehm and Sarita V. Adve in
<a href="https://www.hpl.hp.com/techreports/2008/HPL-2008-56.pdf">Foundations of the C++ Concurrency Memory Model</a>”,
published in PLDI 2008.
The definition of data-race-free programs and the guarantee of sequential consistency
for race-free programs are equivalent to the ones in that work.
</p>
<p>
The memory model describes the requirements on program executions,
which are made up of goroutine executions,
which in turn are made up of memory operations.
</p>
<p>
A <i>memory operation</i> is modeled by four details:
</p>
<ul>
<li>its kind, indicating whether it is an ordinary data read, an ordinary data write,
or a <i>synchronizing operation</i> such as an atomic data access,
a mutex operation, or a channel operation,</li>
<li>its location in the program,</li>
<li>the memory location or variable being accessed, and</li>
<li>the values read or written by the operation.</li>
</ul>
<p>
Some memory operations are <i>read-like</i>, including read, atomic read, mutex lock, and channel receive.
Other memory operations are <i>write-like</i>, including write, atomic write, mutex unlock, channel send, and channel close.
Some, such as atomic compare-and-swap, are both read-like and write-like.
</p>
<p>
A <i>goroutine execution</i> is modeled as a set of memory operations executed by a single goroutine.
</p>
<p>
<b>Requirement 1</b>:
The memory operations in each goroutine must correspond to a correct sequential execution of that goroutine,
given the values read from and written to memory.
That execution must be consistent with the <i>sequenced before</i> relation,
defined as the partial order requirements set out by the <a href="/ref/spec">Go language specification</a>
for Go's control flow constructs as well as the <a href="/ref/spec#Order_of_evaluation">order of evaluation for expressions</a>.
</p>
<p>
A Go <i>program execution</i> is modeled as a set of goroutine executions,
together with a mapping <i>W</i> that specifies the write-like operation that each read-like operation reads from.
(Multiple executions of the same program can have different program executions.)
</p>
<p>
<b>Requirement 2</b>:
For a given program execution, the mapping <i>W</i>, when limited to synchronizing operations,
must be explainable by some implicit total order of the synchronizing operations
that is consistent with sequencing and the values read and written by those operations.
</p>
<p>
The <i>synchronized before</i> relation is a partial order on synchronizing memory operations,
derived from <i>W</i>.
If a synchronizing read-like memory operation <i>r</i>
observes a synchronizing write-like memory operation <i>w</i>
(that is, if <i>W</i>(<i>r</i>) = <i>w</i>),
then <i>w</i> is synchronized before <i>r</i>.
Informally, the synchronized before relation is a subset of the implied total order
mentioned in the previous paragraph,
limited to the information that <i>W</i> directly observes.
</p>
<p>
The <i>happens before</i> relation is defined as the transitive closure of the
union of the sequenced before and synchronized before relations.
</p>
<p>
<b>Requirement 3</b>:
For an ordinary (non-synchronizing) data read <i>r</i> on a memory location <i>x</i>,
<i>W</i>(<i>r</i>) must be a write <i>w</i> that is <i>visible</i> to <i>r</i>,
where visible means that both of the following hold:
</p>
<ol>
<li><i>w</i> happens before <i>r</i>.</li>
<li><i>w</i> does not happen before any other write <i>w'</i> (to <i>x</i>) that happens before <i>r</i>.</li>
</ol>
<p>
A <i>read-write data race</i> on memory location <i>x</i>
consists of a read-like memory operation <i>r</i> on <i>x</i>
and a write-like memory operation <i>w</i> on <i>x</i>,
at least one of which is non-synchronizing,
which are unordered by happens before
(that is, neither <i>r</i> happens before <i>w</i>
nor <i>w</i> happens before <i>r</i>).
</p>
<p>
A <i>write-write data race</i> on memory location <i>x</i>
consists of two write-like memory operations <i>w</i> and <i>w'</i> on <i>x</i>,
at least one of which is non-synchronizing,
which are unordered by happens before.
</p>
<p>
Note that if there are no read-write or write-write data races on memory location <i>x</i>,
then any read <i>r</i> on <i>x</i> has only one possible <i>W</i>(<i>r</i>):
the single <i>w</i> that immediately precedes it in the happens before order.
</p>
<p>
More generally, it can be shown that any Go program that is data-race-free,
meaning it has no program executions with read-write or write-write data races,
can only have outcomes explained by some sequentially consistent interleaving
of the goroutine executions.
(The proof is the same as Section 7 of Boehm and Adve's paper cited above.)
This property is called DRF-SC.
</p>
<p>
The intent of the formal definition is to match
the DRF-SC guarantee provided to race-free programs
by other languages, including C, C++, Java, JavaScript, Rust, and Swift.
</p>
<p>
Certain Go language operations such as goroutine creation and memory allocation
act as synchronization operations.
The effect of these operations on the synchronized-before partial order
is documented in the “Synchronization” section below.
Individual packages are responsible for providing similar documentation
for their own operations.
</p>
<h2 id="restrictions">Implementation Restrictions for Programs Containing Data Races</h2>
<p>
The preceding section gave a formal definition of data-race-free program execution.
This section informally describes the semantics that implementations must provide
for programs that do contain races.
</p>
<p>
Any implementation can, upon detecting a data race,
report the race and halt execution of the program.
Implementations using ThreadSanitizer
(accessed with “<code>go</code> <code>build</code> <code>-race</code>”)
do exactly this.
</p>
<p>
A read of an array, struct, or complex number
may by implemented as a read of each individual sub-value
(array element, struct field, or real/imaginary component),
in any order.
Similarly, a write of an array, struct, or complex number
may be implemented as a write of each individual sub-value,
in any order.
</p>
<p>
A read <i>r</i> of a memory location <i>x</i>
holding a value
that is not larger than a machine word must observe
some write <i>w</i> such that <i>r</i> does not happen before <i>w</i>
and there is no write <i>w'</i> such that <i>w</i> happens before <i>w'</i>
and <i>w'</i> happens before <i>r</i>.
That is, each read must observe a value written by a preceding or concurrent write.
</p>
<p>
Additionally, observation of acausal and “out of thin air” writes is disallowed.
</p>
<p>
Reads of memory locations larger than a single machine word
are encouraged but not required to meet the same semantics
as word-sized memory locations,
observing a single allowed write <i>w</i>.
For performance reasons,
implementations may instead treat larger operations
as a set of individual machine-word-sized operations
in an unspecified order.
This means that races on multiword data structures
can lead to inconsistent values not corresponding to a single write.
When the values depend on the consistency
of internal (pointer, length) or (pointer, type) pairs,
as can be the case for interface values, maps,
slices, and strings in most Go implementations,
such races can in turn lead to arbitrary memory corruption.
</p>
<p>
Examples of incorrect synchronization are given in the
“Incorrect synchronization” section below.
</p>
<p>
Examples of the limitations on implementations are given in the
“Incorrect compilation” section below.
</p>
<h2 id="synchronization">Synchronization</h2>
<h3 id="init">Initialization</h3>
<p>
Program initialization runs in a single goroutine,
but that goroutine may create other goroutines,
which run concurrently.
</p>
<p class="rule">
If a package <code>p</code> imports package <code>q</code>, the completion of
<code>q</code>'s <code>init</code> functions happens before the start of any of <code>p</code>'s.
</p>
<p class="rule">
The completion of all <code>init</code> functions is synchronized before
the start of the function <code>main.main</code>.
</p>
<h3 id="go">Goroutine creation</h3>
<p class="rule">
The <code>go</code> statement that starts a new goroutine
is synchronized before the start of the goroutine's execution.
</p>
<p>
For example, in this program:
</p>
<pre>
var a string
func f() {
print(a)
}
func hello() {
a = "hello, world"
go f()
}
</pre>
<p>
calling <code>hello</code> will print <code>"hello, world"</code>
at some point in the future (perhaps after <code>hello</code> has returned).
</p>
<h3 id="goexit">Goroutine destruction</h3>
<p>
The exit of a goroutine is not guaranteed to be synchronized before
any event in the program.
For example, in this program:
</p>
<pre>
var a string
func hello() {
go func() { a = "hello" }()
print(a)
}
</pre>
<p>
the assignment to <code>a</code> is not followed by
any synchronization event, so it is not guaranteed to be
observed by any other goroutine.
In fact, an aggressive compiler might delete the entire <code>go</code> statement.
</p>
<p>
If the effects of a goroutine must be observed by another goroutine,
use a synchronization mechanism such as a lock or channel
communication to establish a relative ordering.
</p>
<h3 id="chan">Channel communication</h3>
<p>
Channel communication is the main method of synchronization
between goroutines. Each send on a particular channel
is matched to a corresponding receive from that channel,
usually in a different goroutine.
</p>
<p class="rule">
A send on a channel is synchronized before the completion of the
corresponding receive from that channel.
</p>
<p>
This program:
</p>
<pre>
var c = make(chan int, 10)
var a string
func f() {
a = "hello, world"
c &lt;- 0
}
func main() {
go f()
&lt;-c
print(a)
}
</pre>
<p>
is guaranteed to print <code>"hello, world"</code>. The write to <code>a</code>
is sequenced before the send on <code>c</code>, which is synchronized before
the corresponding receive on <code>c</code> completes, which is sequenced before
the <code>print</code>.
</p>
<p class="rule">
The closing of a channel is synchronized before a receive that returns a zero value
because the channel is closed.
</p>
<p>
In the previous example, replacing
<code>c &lt;- 0</code> with <code>close(c)</code>
yields a program with the same guaranteed behavior.
</p>
<p class="rule">
A receive from an unbuffered channel is synchronized before the completion of
the corresponding send on that channel.
</p>
<p>
This program (as above, but with the send and receive statements swapped and
using an unbuffered channel):
</p>
<pre>
var c = make(chan int)
var a string
func f() {
a = "hello, world"
&lt;-c
}
func main() {
go f()
c &lt;- 0
print(a)
}
</pre>
<p>
is also guaranteed to print <code>"hello, world"</code>. The write to <code>a</code>
is sequenced before the receive on <code>c</code>, which is synchronized before
the corresponding send on <code>c</code> completes, which is sequenced
before the <code>print</code>.
</p>
<p>
If the channel were buffered (e.g., <code>c = make(chan int, 1)</code>)
then the program would not be guaranteed to print
<code>"hello, world"</code>. (It might print the empty string,
crash, or do something else.)
</p>
<p class="rule">
The <i>k</i>th receive on a channel with capacity <i>C</i> is synchronized before the completion of the <i>k</i>+<i>C</i>th send from that channel completes.
</p>
<p>
This rule generalizes the previous rule to buffered channels.
It allows a counting semaphore to be modeled by a buffered channel:
the number of items in the channel corresponds to the number of active uses,
the capacity of the channel corresponds to the maximum number of simultaneous uses,
sending an item acquires the semaphore, and receiving an item releases
the semaphore.
This is a common idiom for limiting concurrency.
</p>
<p>
This program starts a goroutine for every entry in the work list, but the
goroutines coordinate using the <code>limit</code> channel to ensure
that at most three are running work functions at a time.
</p>
<pre>
var limit = make(chan int, 3)
func main() {
for _, w := range work {
go func(w func()) {
limit &lt;- 1
w()
&lt;-limit
}(w)
}
select{}
}
</pre>
<h3 id="locks">Locks</h3>
<p>
The <code>sync</code> package implements two lock data types,
<code>sync.Mutex</code> and <code>sync.RWMutex</code>.
</p>
<p class="rule">
For any <code>sync.Mutex</code> or <code>sync.RWMutex</code> variable <code>l</code> and <i>n</i> &lt; <i>m</i>,
call <i>n</i> of <code>l.Unlock()</code> is synchronized before call <i>m</i> of <code>l.Lock()</code> returns.
</p>
<p>
This program:
</p>
<pre>
var l sync.Mutex
var a string
func f() {
a = "hello, world"
l.Unlock()
}
func main() {
l.Lock()
go f()
l.Lock()
print(a)
}
</pre>
<p>
is guaranteed to print <code>"hello, world"</code>.
The first call to <code>l.Unlock()</code> (in <code>f</code>) is synchronized
before the second call to <code>l.Lock()</code> (in <code>main</code>) returns,
which is sequenced before the <code>print</code>.
</p>
<p class="rule">
For any call to <code>l.RLock</code> on a <code>sync.RWMutex</code> variable <code>l</code>,
there is an <i>n</i> such that the <i>n</i>th call to <code>l.Unlock</code>
is synchronized before the return from <code>l.RLock</code>,
and the matching call to <code>l.RUnlock</code> is synchronized before the return from call <i>n</i>+1 to <code>l.Lock</code>.
</p>
<p class="rule">
A successful call to <code>l.TryLock</code> (or <code>l.TryRLock</code>)
is equivalent to a call to <code>l.Lock</code> (or <code>l.RLock</code>).
An unsuccessful call has no synchronizing effect at all.
As far as the memory model is concerned,
<code>l.TryLock</code> (or <code>l.TryRLock</code>)
may be considered to be able to return false
even when the mutex <i>l</i> is unlocked.
</p>
<h3 id="once">Once</h3>
<p>
The <code>sync</code> package provides a safe mechanism for
initialization in the presence of multiple goroutines
through the use of the <code>Once</code> type.
Multiple threads can execute <code>once.Do(f)</code> for a particular <code>f</code>,
but only one will run <code>f()</code>, and the other calls block
until <code>f()</code> has returned.
</p>
<p class="rule">
The completion of a single call of <code>f()</code> from <code>once.Do(f)</code>
is synchronized before the return of any call of <code>once.Do(f)</code>.
</p>
<p>
In this program:
</p>
<pre>
var a string
var once sync.Once
func setup() {
a = "hello, world"
}
func doprint() {
once.Do(setup)
print(a)
}
func twoprint() {
go doprint()
go doprint()
}
</pre>
<p>
calling <code>twoprint</code> will call <code>setup</code> exactly
once.
The <code>setup</code> function will complete before either call
of <code>print</code>.
The result will be that <code>"hello, world"</code> will be printed
twice.
</p>
<h3 id="atomic">Atomic Values</h3>
<p>
The APIs in the <a href="/pkg/sync/atomic/"><code>sync/atomic</code></a>
package are collectively “atomic operations”
that can be used to synchronize the execution of different goroutines.
If the effect of an atomic operation <i>A</i> is observed by atomic operation <i>B</i>,
then <i>A</i> is synchronized before <i>B</i>.
All the atomic operations executed in a program behave as though executed
in some sequentially consistent order.
</p>
<p>
The preceding definition has the same semantics as C++s sequentially consistent atomics
and Javas <code>volatile</code> variables.
</p>
<h3 id="finalizer">Finalizers</h3>
<p>
The <a href="/pkg/runtime/"><code>runtime</code></a> package provides
a <code>SetFinalizer</code> function that adds a finalizer to be called when
a particular object is no longer reachable by the program.
A call to <code>SetFinalizer(x, f)</code> is synchronized before the finalization call <code>f(x)</code>.
</p>
<h3 id="more">Additional Mechanisms</h3>
<p>
The <code>sync</code> package provides additional synchronization abstractions,
including <a href="/pkg/sync/#Cond">condition variables</a>,
<a href="/pkg/sync/#Map">lock-free maps</a>,
<a href="/pkg/sync/#Pool">allocation pools</a>,
and
<a href="/pkg/sync/#WaitGroup">wait groups</a>.
The documentation for each of these specifies the guarantees it
makes concerning synchronization.
</p>
<p>
Other packages that provide synchronization abstractions
should document the guarantees they make too.
</p>
<h2 id="badsync">Incorrect synchronization</h2>
<p>
Programs with races are incorrect and
can exhibit non-sequentially consistent executions.
In particular, note that a read <i>r</i> may observe the value written by any write <i>w</i>
that executes concurrently with <i>r</i>.
Even if this occurs, it does not imply that reads happening after <i>r</i>
will observe writes that happened before <i>w</i>.
</p>
<p>
In this program:
</p>
<pre>
var a, b int
func f() {
a = 1
b = 2
}
func g() {
print(b)
print(a)
}
func main() {
go f()
g()
}
</pre>
<p>
it can happen that <code>g</code> prints <code>2</code> and then <code>0</code>.
</p>
<p>
This fact invalidates a few common idioms.
</p>
<p>
Double-checked locking is an attempt to avoid the overhead of synchronization.
For example, the <code>twoprint</code> program might be
incorrectly written as:
</p>
<pre>
var a string
var done bool
func setup() {
a = "hello, world"
done = true
}
func doprint() {
if !done {
once.Do(setup)
}
print(a)
}
func twoprint() {
go doprint()
go doprint()
}
</pre>
<p>
but there is no guarantee that, in <code>doprint</code>, observing the write to <code>done</code>
implies observing the write to <code>a</code>. This
version can (incorrectly) print an empty string
instead of <code>"hello, world"</code>.
</p>
<p>
Another incorrect idiom is busy waiting for a value, as in:
</p>
<pre>
var a string
var done bool
func setup() {
a = "hello, world"
done = true
}
func main() {
go setup()
for !done {
}
print(a)
}
</pre>
<p>
As before, there is no guarantee that, in <code>main</code>,
observing the write to <code>done</code>
implies observing the write to <code>a</code>, so this program could
print an empty string too.
Worse, there is no guarantee that the write to <code>done</code> will ever
be observed by <code>main</code>, since there are no synchronization
events between the two threads. The loop in <code>main</code> is not
guaranteed to finish.
</p>
<p>
There are subtler variants on this theme, such as this program.
</p>
<pre>
type T struct {
msg string
}
var g *T
func setup() {
t := new(T)
t.msg = "hello, world"
g = t
}
func main() {
go setup()
for g == nil {
}
print(g.msg)
}
</pre>
<p>
Even if <code>main</code> observes <code>g != nil</code> and exits its loop,
there is no guarantee that it will observe the initialized
value for <code>g.msg</code>.
</p>
<p>
In all these examples, the solution is the same:
use explicit synchronization.
</p>
<h2 id="badcompiler">Incorrect compilation</h2>
<p>
The Go memory model restricts compiler optimizations as much as it does Go programs.
Some compiler optimizations that would be valid in single-threaded programs are not valid in all Go programs.
In particular, a compiler must not introduce writes that do not exist in the original program,
it must not allow a single read to observe multiple values,
and it must not allow a single write to write multiple values.
</p>
<p>
All the following examples assume that `*p` and `*q` refer to
memory locations accessible to multiple goroutines.
</p>
<p>
Not introducing data races into race-free programs means not moving
writes out of conditional statements in which they appear.
For example, a compiler must not invert the conditional in this program:
</p>
<pre>
*p = 1
if cond {
*p = 2
}
</pre>
<p>
That is, the compiler must not rewrite the program into this one:
</p>
<pre>
*p = 2
if !cond {
*p = 1
}
</pre>
<p>
If <code>cond</code> is false and another goroutine is reading <code>*p</code>,
then in the original program, the other goroutine can only observe any prior value of <code>*p</code> and <code>1</code>.
In the rewritten program, the other goroutine can observe <code>2</code>, which was previously impossible.
</p>
<p>
Not introducing data races also means not assuming that loops terminate.
For example, a compiler must in general not move the accesses to <code>*p</code> or <code>*q</code>
ahead of the loop in this program:
</p>
<pre>
n := 0
for e := list; e != nil; e = e.next {
n++
}
i := *p
*q = 1
</pre>
<p>
If <code>list</code> pointed to a cyclic list,
then the original program would never access <code>*p</code> or <code>*q</code>,
but the rewritten program would.
(Moving `*p` ahead would be safe if the compiler can prove `*p` will not panic;
moving `*q` ahead would also require the compiler proving that no other
goroutine can access `*q`.)
</p>
<p>
Not introducing data races also means not assuming that called functions
always return or are free of synchronization operations.
For example, a compiler must not move the accesses to <code>*p</code> or <code>*q</code>
ahead of the function call in this program
(at least not without direct knowledge of the precise behavior of <code>f</code>):
</p>
<pre>
f()
i := *p
*q = 1
</pre>
<p>
If the call never returned, then once again the original program
would never access <code>*p</code> or <code>*q</code>, but the rewritten program would.
And if the call contained synchronizing operations, then the original program
could establish happens before edges preceding the accesses
to <code>*p</code> and <code>*q</code>, but the rewritten program would not.
</p>
<p>
Not allowing a single read to observe multiple values means
not reloading local variables from shared memory.
For example, a compiler must not discard <code>i</code> and reload it
a second time from <code>*p</code> in this program:
</p>
<pre>
i := *p
if i &lt; 0 || i &gt;= len(funcs) {
panic("invalid function index")
}
... complex code ...
// compiler must NOT reload i = *p here
funcs[i]()
</pre>
<p>
If the complex code needs many registers, a compiler for single-threaded programs
could discard <code>i</code> without saving a copy and then reload
<code>i = *p</code> just before
<code>funcs[i]()</code>.
A Go compiler must not, because the value of <code>*p</code> may have changed.
(Instead, the compiler could spill <code>i</code> to the stack.)
</p>
<p>
Not allowing a single write to write multiple values also means not using
the memory where a local variable will be written as temporary storage before the write.
For example, a compiler must not use <code>*p</code> as temporary storage in this program:
</p>
<pre>
*p = i + *p/2
</pre>
<p>
That is, it must not rewrite the program into this one:
</p>
<pre>
*p /= 2
*p += i
</pre>
<p>
If <code>i</code> and <code>*p</code> start equal to 2,
the original code does <code>*p = 3</code>,
so a racing thread can read only 2 or 3 from <code>*p</code>.
The rewritten code does <code>*p = 1</code> and then <code>*p = 3</code>,
allowing a racing thread to read 1 as well.
</p>
<p>
Note that all these optimizations are permitted in C/C++ compilers:
a Go compiler sharing a back end with a C/C++ compiler must take care
to disable optimizations that are invalid for Go.
</p>
<p>
Note that the prohibition on introducing data races
does not apply if the compiler can prove that the races
do not affect correct execution on the target platform.
For example, on essentially all CPUs, it is valid to rewrite
</p>
<pre>
n := 0
for i := 0; i < m; i++ {
n += *shared
}
</pre>
into:
<pre>
n := 0
local := *shared
for i := 0; i < m; i++ {
n += local
}
</pre>
<p>
provided it can be proved that <code>*shared</code> will not fault on access,
because the potential added read will not affect any existing concurrent reads or writes.
On the other hand, the rewrite would not be valid in a source-to-source translator.
</p>
<h2 id="conclusion">Conclusion</h2>
<p>
Go programmers writing data-race-free programs can rely on
sequentially consistent execution of those programs,
just as in essentially all other modern programming languages.
</p>
<p>
When it comes to programs with races,
both programmers and compilers should remember the advice:
don't be clever.
</p>

8828
doc/go_spec.html Normal file

File diff suppressed because it is too large Load Diff

363
doc/godebug.md Normal file
View File

@@ -0,0 +1,363 @@
---
title: "Go, Backwards Compatibility, and GODEBUG"
layout: article
---
<!--
This document is kept in the Go repo, not x/website,
because it documents the full list of known GODEBUG settings,
which are tied to a specific release.
-->
## Introduction {#intro}
Go's emphasis on backwards compatibility is one of its key strengths.
There are, however, times when we cannot maintain complete compatibility.
If code depends on buggy (including insecure) behavior,
then fixing the bug will break that code.
New features can also have similar impacts:
enabling the HTTP/2 use by the HTTP client broke programs
connecting to servers with buggy HTTP/2 implementations.
These kinds of changes are unavoidable and
[permitted by the Go 1 compatibility rules](/doc/go1compat).
Even so, Go provides a mechanism called GODEBUG to
reduce the impact such changes have on Go developers
using newer toolchains to compile old code.
A GODEBUG setting is a `key=value` pair
that controls the execution of certain parts of a Go program.
The environment variable `GODEBUG`
can hold a comma-separated list of these settings.
For example, if a Go program is running in an environment that contains
GODEBUG=http2client=0,http2server=0
then that Go program will disable the use of HTTP/2 by default in both
the HTTP client and the HTTP server.
It is also possible to set the default `GODEBUG` for a given program
(discussed below).
When preparing any change that is permitted by Go 1 compatibility
but may nonetheless break some existing programs,
we first engineer the change to keep as many existing programs working as possible.
For the remaining programs,
we define a new GODEBUG setting that
allows individual programs to opt back in to the old behavior.
A GODEBUG setting may not be added if doing so is infeasible,
but that should be extremely rare.
GODEBUG settings added for compatibility will be maintained
for a minimum of two years (four Go releases).
Some, such as `http2client` and `http2server`,
will be maintained much longer, even indefinitely.
When possible, each GODEBUG setting has an associated
[runtime/metrics](/pkg/runtime/metrics/) counter
named `/godebug/non-default-behavior/<name>:events`
that counts the number of times a particular program's
behavior has changed based on a non-default value
for that setting.
For example, when `GODEBUG=http2client=0` is set,
`/godebug/non-default-behavior/http2client:events`
counts the number of HTTP transports that the program
has configured without HTTP/2 support.
## Default GODEBUG Values {#default}
When a GODEBUG setting is not listed in the environment variable,
its value is derived from three sources:
the defaults for the Go toolchain used to build the program,
amended to match the Go version listed in `go.mod`,
and then overridden by explicit `//go:debug` lines in the program.
The [GODEBUG History](#history) gives the exact defaults for each Go toolchain version.
For example, Go 1.21 introduces the `panicnil` setting,
controlling whether `panic(nil)` is allowed;
it defaults to `panicnil=0`, making `panic(nil)` a run-time error.
Using `panicnil=1` restores the behavior of Go 1.20 and earlier.
When compiling a work module or workspace that declares
an older Go version, the Go toolchain amends its defaults
to match that older Go version as closely as possible.
For example, when a Go 1.21 toolchain compiles a program,
if the work module's `go.mod` or the workspace's `go.work`
says `go` `1.20`, then the program defaults to `panicnil=1`,
matching Go 1.20 instead of Go 1.21.
Because this method of setting GODEBUG defaults was introduced only in Go 1.21,
programs listing versions of Go earlier than Go 1.20 are configured to match Go 1.20,
not the older version.
To override these defaults, starting in Go 1.23, the work module's `go.mod`
or the workspace's `go.work` can list one or more `godebug` lines:
godebug (
default=go1.21
panicnil=1
asynctimerchan=0
)
The special key `default` indicates a Go version to take unspecified
settings from. This allows setting the GODEBUG defaults separately
from the Go language version in the module.
In this example, the program is asking for Go 1.21 semantics and
then asking for the old pre-Go 1.21 `panic(nil)` behavior and the
new Go 1.23 `asynctimerchan=0` behavior.
Only the work module's `go.mod` is consulted for `godebug` directives.
Any directives in required dependency modules are ignored.
It is an error to list a `godebug` with an unrecognized setting.
(Toolchains older than Go 1.23 reject all `godebug` lines, since they do not
understand `godebug` at all.)
The defaults from the `go` and `godebug` lines apply to all main
packages that are built. For more fine-grained control,
starting in Go 1.21, a main package's source files
can include one or more `//go:debug` directives at the top of the file
(preceding the `package` statement).
The `godebug` lines in the previous example would be written:
//go:debug default=go1.21
//go:debug panicnil=1
//go:debug asynctimerchan=0
Starting in Go 1.21, the Go toolchain treats a `//go:debug` directive
with an unrecognized GODEBUG setting as an invalid program.
Programs with more than one `//go:debug` line for a given setting
are also treated as invalid.
(Older toolchains ignore `//go:debug` directives entirely.)
The defaults that will be compiled into a main package
are reported by the command:
{{raw `
go list -f '{{.DefaultGODEBUG}}' my/main/package
`}}
Only differences from the base Go toolchain defaults are reported.
When testing a package, `//go:debug` lines in the `*_test.go`
files are treated as directives for the test's main package.
In any other context, `//go:debug` lines are ignored by the toolchain;
`go` `vet` reports such lines as misplaced.
## GODEBUG History {#history}
This section documents the GODEBUG settings introduced and removed in each major Go release
for compatibility reasons.
Packages or programs may define additional settings for internal debugging purposes;
for example,
see the [runtime documentation](/pkg/runtime#hdr-Environment_Variables)
and the [go command documentation](/cmd/go#hdr-Build_and_test_caching).
### Go 1.23
Go 1.23 changed the channels created by package time to be unbuffered
(synchronous), which makes correct use of the [`Timer.Stop`](/pkg/time/#Timer.Stop)
and [`Timer.Reset`](/pkg/time/#Timer.Reset) method results much easier.
The [`asynctimerchan` setting](/pkg/time/#NewTimer) disables this change.
There are no runtime metrics for this change,
This setting may be removed in a future release, Go 1.27 at the earliest.
Go 1.23 changed the mode bits reported by [`os.Lstat`](/pkg/os#Lstat) and [`os.Stat`](/pkg/os#Stat)
for reparse points, which can be controlled with the `winsymlink` setting.
As of Go 1.23 (`winsymlink=1`), mount points no longer have [`os.ModeSymlink`](/pkg/os#ModeSymlink)
set, and reparse points that are not symlinks, Unix sockets, or dedup files now
always have [`os.ModeIrregular`](/pkg/os#ModeIrregular) set. As a result of these changes,
[`filepath.EvalSymlinks`](/pkg/path/filepath#EvalSymlinks) no longer evaluates
mount points, which was a source of many inconsistencies and bugs.
At previous versions (`winsymlink=0`), mount points are treated as symlinks,
and other reparse points with non-default [`os.ModeType`](/pkg/os#ModeType) bits
(such as [`os.ModeDir`](/pkg/os#ModeDir)) do not have the `ModeIrregular` bit set.
Go 1.23 changed [`os.Readlink`](/pkg/os#Readlink) and [`filepath.EvalSymlinks`](/pkg/path/filepath#EvalSymlinks)
to avoid trying to normalize volumes to drive letters, which was not always even possible.
This behavior is controlled by the `winreadlinkvolume` setting.
For Go 1.23, it defaults to `winreadlinkvolume=1`.
Previous versions default to `winreadlinkvolume=0`.
Go 1.23 enabled the experimental post-quantum key exchange mechanism
X25519Kyber768Draft00 by default. The default can be reverted using the
[`tlskyber` setting](/pkg/crypto/tls/#Config.CurvePreferences).
Go 1.23 changed the behavior of
[crypto/x509.ParseCertificate](/pkg/crypto/x509/#ParseCertificate) to reject
serial numbers that are negative. This change can be reverted with
the [`x509negativeserial` setting](/pkg/crypto/x509/#ParseCertificate).
Go 1.23 re-enabled support in html/template for ECMAScript 6 template literals by default.
The [`jstmpllitinterp` setting](/pkg/html/template#hdr-Security_Model) no longer has
any effect.
Go 1.23 changed the default TLS cipher suites used by clients and servers when
not explicitly configured, removing 3DES cipher suites. The default can be reverted
using the [`tls3des` setting](/pkg/crypto/tls/#Config.CipherSuites).
Go 1.23 changed the behavior of [`tls.X509KeyPair`](/pkg/crypto/tls#X509KeyPair)
and [`tls.LoadX509KeyPair`](/pkg/crypto/tls#LoadX509KeyPair) to populate the
Leaf field of the returned [`tls.Certificate`](/pkg/crypto/tls#Certificate).
This behavior is controlled by the `x509keypairleaf` setting. For Go 1.23, it
defaults to `x509keypairleaf=1`. Previous versions default to
`x509keypairleaf=0`.
Go 1.23 changed
[`net/http.ServeContent`](/pkg/net/http#ServeContent),
[`net/http.ServeFile`](/pkg/net/http#ServeFile), and
[`net/http.ServeFS`](/pkg/net/http#ServeFS) to
remove Cache-Control, Content-Encoding, Etag, and Last-Modified headers
when serving an error. This behavior is controlled by
the [`httpservecontentkeepheaders` setting](/pkg/net/http#ServeContent).
Using `httpservecontentkeepheaders=1` restores the pre-Go 1.23 behavior.
### Go 1.22
Go 1.22 adds a configurable limit to control the maximum acceptable RSA key size
that can be used in TLS handshakes, controlled by the [`tlsmaxrsasize` setting](/pkg/crypto/tls#Conn.Handshake).
The default is tlsmaxrsasize=8192, limiting RSA to 8192-bit keys. To avoid
denial of service attacks, this setting and default was backported to Go
1.19.13, Go 1.20.8, and Go 1.21.1.
Go 1.22 made it an error for a request or response read by a net/http
client or server to have an empty Content-Length header.
This behavior is controlled by the `httplaxcontentlength` setting.
Go 1.22 changed the behavior of ServeMux to accept extended
patterns and unescape both patterns and request paths by segment.
This behavior can be controlled by the
[`httpmuxgo121` setting](/pkg/net/http/#ServeMux).
Go 1.22 added the [Alias type](/pkg/go/types#Alias) to [go/types](/pkg/go/types)
for the explicit representation of [type aliases](/ref/spec#Type_declarations).
Whether the type checker produces `Alias` types or not is controlled by the
[`gotypesalias` setting](/pkg/go/types#Alias).
For Go 1.22 it defaults to `gotypesalias=0`.
For Go 1.23, `gotypesalias=1` will become the default.
This setting will be removed in a future release, Go 1.27 at the earliest.
Go 1.22 changed the default minimum TLS version supported by both servers
and clients to TLS 1.2. The default can be reverted to TLS 1.0 using the
[`tls10server` setting](/pkg/crypto/tls/#Config).
Go 1.22 changed the default TLS cipher suites used by clients and servers when
not explicitly configured, removing the cipher suites which used RSA based key
exchange. The default can be reverted using the [`tlsrsakex` setting](/pkg/crypto/tls/#Config).
Go 1.22 disabled
[`ConnectionState.ExportKeyingMaterial`](/pkg/crypto/tls/#ConnectionState.ExportKeyingMaterial)
when the connection supports neither TLS 1.3 nor Extended Master Secret
(implemented in Go 1.21). It can be reenabled with the [`tlsunsafeekm`
setting](/pkg/crypto/tls/#ConnectionState.ExportKeyingMaterial).
Go 1.22 changed how the runtime interacts with transparent huge pages on Linux.
In particular, a common default Linux kernel configuration can result in
significant memory overheads, and Go 1.22 no longer works around this default.
To work around this issue without adjusting kernel settings, transparent huge
pages can be disabled for Go memory with the
[`disablethp` setting](/pkg/runtime#hdr-Environment_Variable).
This behavior was backported to Go 1.21.1, but the setting is only available
starting with Go 1.21.6.
This setting may be removed in a future release, and users impacted by this issue
should adjust their Linux configuration according to the recommendations in the
[GC guide](/doc/gc-guide#Linux_transparent_huge_pages), or switch to a Linux
distribution that disables transparent huge pages altogether.
Go 1.22 added contention on runtime-internal locks to the [`mutex`
profile](/pkg/runtime/pprof#Profile). Contention on these locks is always
reported at `runtime._LostContendedRuntimeLock`. Complete stack traces of
runtime locks can be enabled with the [`runtimecontentionstacks`
setting](/pkg/runtime#hdr-Environment_Variable). These stack traces have
non-standard semantics, see setting documentation for details.
Go 1.22 added a new [`crypto/x509.Certificate`](/pkg/crypto/x509/#Certificate)
field, [`Policies`](/pkg/crypto/x509/#Certificate.Policies), which supports
certificate policy OIDs with components larger than 31 bits. By default this
field is only used during parsing, when it is populated with policy OIDs, but
not used during marshaling. It can be used to marshal these larger OIDs, instead
of the existing PolicyIdentifiers field, by using the
[`x509usepolicies` setting.](/pkg/crypto/x509/#CreateCertificate).
### Go 1.21
Go 1.21 made it a run-time error to call `panic` with a nil interface value,
controlled by the [`panicnil` setting](/pkg/builtin/#panic).
Go 1.21 made it an error for html/template actions to appear inside of an ECMAScript 6
template literal, controlled by the
[`jstmpllitinterp` setting](/pkg/html/template#hdr-Security_Model).
This behavior was backported to Go 1.19.8+ and Go 1.20.3+.
Go 1.21 introduced a limit on the maximum number of MIME headers and multipart
forms, controlled by the
[`multipartmaxheaders` and `multipartmaxparts` settings](/pkg/mime/multipart#hdr-Limits)
respectively.
This behavior was backported to Go 1.19.8+ and Go 1.20.3+.
Go 1.21 adds the support of Multipath TCP but it is only used if the application
explicitly asked for it. This behavior can be controlled by the
[`multipathtcp` setting](/pkg/net#Dialer.SetMultipathTCP).
There is no plan to remove any of these settings.
### Go 1.20
Go 1.20 introduced support for rejecting insecure paths in tar and zip archives,
controlled by the [`tarinsecurepath` setting](/pkg/archive/tar/#Reader.Next)
and the [`zipinsecurepath` setting](/pkg/archive/zip/#NewReader).
These default to `tarinsecurepath=1` and `zipinsecurepath=1`,
preserving the behavior of earlier versions of Go.
A future version of Go may change the defaults to
`tarinsecurepath=0` and `zipinsecurepath=0`.
Go 1.20 introduced automatic seeding of the
[`math/rand`](/pkg/math/rand) global random number generator,
controlled by the [`randautoseed` setting](/pkg/math/rand/#Seed).
Go 1.20 introduced the concept of fallback roots for use during certificate verification,
controlled by the [`x509usefallbackroots` setting](/pkg/crypto/x509/#SetFallbackRoots).
Go 1.20 removed the preinstalled `.a` files for the standard library
from the Go distribution.
Installations now build and cache the standard library like
packages in other modules.
The [`installgoroot` setting](/cmd/go#hdr-Compile_and_install_packages_and_dependencies)
restores the installation and use of preinstalled `.a` files.
There is no plan to remove any of these settings.
### Go 1.19
Go 1.19 made it an error for path lookups to resolve to binaries in the current directory,
controlled by the [`execerrdot` setting](/pkg/os/exec#hdr-Executables_in_the_current_directory).
There is no plan to remove this setting.
Go 1.19 started sending EDNS0 additional headers on DNS requests.
This can reportedly break the DNS server provided on some routers,
such as CenturyLink Zyxel C3000Z.
This can be changed by the [`netedns0` setting](/pkg/net#hdr-Name_Resolution).
This setting is available in Go 1.21.12, Go 1.22.5, Go 1.23, and later.
There is no plan to remove this setting.
### Go 1.18
Go 1.18 removed support for SHA1 in most X.509 certificates,
controlled by the [`x509sha1` setting](/pkg/crypto/x509#InsecureAlgorithmError).
This setting will be removed in a future release, Go 1.22 at the earliest.
### Go 1.10
Go 1.10 changed how build caching worked and added test caching, along
with the [`gocacheverify`, `gocachehash`, and `gocachetest` settings](/cmd/go/#hdr-Build_and_test_caching).
There is no plan to remove these settings.
### Go 1.6
Go 1.6 introduced transparent support for HTTP/2,
controlled by the [`http2client`, `http2server`, and `http2debug` settings](/pkg/net/http/#hdr-HTTP_2).
There is no plan to remove these settings.
### Go 1.5
Go 1.5 introduced a pure Go DNS resolver,
controlled by the [`netdns` setting](/pkg/net/#hdr-Name_Resolution).
There is no plan to remove this setting.

14
doc/initial/1-intro.md Normal file
View File

@@ -0,0 +1,14 @@
<!--
NOTE: In this document and others in this directory, the convention is to
set fixed-width phrases with non-fixed-width spaces, as in
`hello` `world`.
-->
<style>
main ul li { margin: 0.5em 0; }
</style>
## DRAFT RELEASE NOTES — Introduction to Go 1.N {#introduction}
**Go 1.N is not yet released. These are work-in-progress release notes.
Go 1.N is expected to be released in {Month} {Year}.**

View File

@@ -0,0 +1,3 @@
## Changes to the language {#language}

6
doc/initial/3-tools.md Normal file
View File

@@ -0,0 +1,6 @@
## Tools {#tools}
### Go command {#go-command}
### Cgo {#cgo}

1
doc/initial/4-runtime.md Normal file
View File

@@ -0,0 +1 @@
## Runtime {#runtime}

View File

@@ -0,0 +1,7 @@
## Compiler {#compiler}
## Assembler {#assembler}
## Linker {#linker}

View File

@@ -0,0 +1,2 @@
## Standard library {#library}

View File

@@ -0,0 +1,3 @@
### Minor changes to the library {#minor_library_changes}

View File

@@ -0,0 +1 @@
API changes and other small changes to the standard library go here.

2
doc/initial/7-ports.md Normal file
View File

@@ -0,0 +1,2 @@
## Ports {#ports}