[インデックス 18888] ファイルの概要
このコミットは、Go言語のランタイムにおける特定の変更を元に戻すものです。具体的には、以前のコミット CL 77050045
(ハッシュ 073d79675aae
) によって導入された、自己参照型配列に関するテストコードの追加を取り消しています。この取り消しは、元の変更が「すべてのビルドを破壊する」という重大な問題を引き起こしたためです。
コミット
commit 088b9a3c3da1b759038050e1c1ce91e09d369f17
Author: Brad Fitzpatrick <bradfitz@golang.org>
Date: Mon Mar 17 20:00:44 2014 -0700
undo CL 77050045 / 073d79675aae
Breaks all builds.
««« original CL description
cmd/gc: Add tests for self-referential array types.
LGTM=gri, iant
R=gri, iant
CC=golang-codereviews
https://golang.org/cl/77050045
»»»
TBR=cmang
R=cmang
CC=golang-codereviews
https://golang.org/cl/77210043
---
test/fixedbugs/issue7525.go | 19 -------------------
1 file changed, 19 deletions(-)
diff --git a/test/fixedbugs/issue7525.go b/test/fixedbugs/issue7525.go
deleted file mode 100644
index 6ded706098..0000000000
--- a/test/fixedbugs/issue7525.go
+++ /dev/null
@@ -1,19 +0,0 @@
-// errorcheck
-//
-// Copyright 2014 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.
-//
-// Issue 7525: self-referential array types.
-//
-// package main
-//
-// import "unsafe"
-//
-// var x struct {
-// a [unsafe.Sizeof(x.a)]int // ERROR "array bound|invalid array"
-// b [unsafe.Offsetof(x.b)]int // ERROR "array bound|invalid array"
-// c [unsafe.Alignof(x.c)]int // ERROR "array bound|invalid array"
-// d [len(x.d)]int // ERROR "array bound|invalid array"
-// e [cap(x.e)]int // ERROR "array bound|invalid array"
-// }
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/088b9a3c3da1b759038050e1c1ce91e09d369f17
元コミット内容
このコミットは、CL 77050045
(ハッシュ 073d79675aae
) の内容を元に戻すものです。元のコミットの目的は、cmd/gc
(Goコンパイラ) に対して自己参照型配列のテストを追加することでした。具体的には、test/fixedbugs/issue7525.go
というファイルが追加され、構造体内の配列のサイズ定義に unsafe.Sizeof
, unsafe.Offsetof
, unsafe.Alignof
, len
, cap
といった自己参照的な式を使用した場合のエラーチェックを行うものでした。
元のコミットメッセージは以下の通りです。
cmd/gc: Add tests for self-referential array types.
LGTM=gri, iant
R=gri, iant
CC=golang-codereviews
https://golang.org/cl/77050045
変更の背景
このコミットの背景には、元の CL 77050045
がGoのビルドシステム全体に深刻な問題を引き起こしたという事実があります。コミットメッセージに明記されている「Breaks all builds. (すべてのビルドを破壊する)」という記述が、その緊急性と重大性を示しています。
Go言語の開発プロセスでは、変更がコミットされる前に自動テストや継続的インテグレーション (CI) システムによって検証されます。しかし、このケースでは、元の変更が何らかの形でCIシステムをすり抜け、あるいはCIシステムでは検出できないような、より広範なビルド環境に影響を与える問題を引き起こしたと考えられます。
このような状況では、問題の原因を特定して修正するよりも、まず問題のある変更を元に戻し、ビルドシステムを安定した状態に戻すことが最優先されます。そのため、このコミットは、問題を引き起こしたテストファイル test/fixedbugs/issue7525.go
を削除することで、元の変更を完全にロールバックしています。
前提知識の解説
このコミットを理解するためには、以下のGo言語の概念と開発プロセスに関する知識が必要です。
- Go言語の型システム: Goは静的型付け言語であり、変数は特定の型を持ちます。配列もまた型の一つであり、そのサイズはコンパイル時に決定される必要があります。
- 自己参照型 (Self-referential types): ある型がその定義の中で自分自身を参照する構造を指します。例えば、構造体のフィールドがその構造体自身のサイズやオフセットに依存する場合などです。
unsafe
パッケージ: Go言語のunsafe
パッケージは、Goの型システムやメモリ安全性の保証をバイパスする低レベルな操作を可能にします。これには、ポインタとuintptr
の間の変換、任意の型のサイズ、アライメント、オフセットの取得などが含まれます。unsafe.Sizeof(x)
:x
のメモリ上でのサイズ(バイト単位)を返します。unsafe.Offsetof(x.f)
: 構造体x
のフィールドf
のオフセット(構造体の先頭からのバイト数)を返します。unsafe.Alignof(x)
:x
のアライメント(メモリ上での配置制約)を返します。
- 配列のサイズ: Goの配列は固定長であり、そのサイズは型の一部です。
[N]T
の形式で宣言され、N
は配列の要素数を示す定数式である必要があります。 len
とcap
: スライスや配列の長さ (len
) や容量 (cap
) を取得する組み込み関数です。これらは通常、実行時に評価されますが、コンパイル時に定数として評価できる場合もあります。- Goコンパイラ (
cmd/gc
): Go言語の公式コンパイラです。ソースコードを機械語に変換する過程で、型チェック、構文解析、最適化などを行います。 - Goのコードレビュープロセス (CL): Goプロジェクトでは、すべての変更はChange List (CL) として提出され、レビューアによって承認される必要があります。
LGTM
(Looks Good To Me) は承認を示すサインオフです。R
はレビューア、TBR
(To Be Reviewed) はレビューを依頼する人を示します。 - 継続的インテグレーション (CI): ソフトウェア開発において、開発者がコードベースに加えた変更を頻繁に統合し、自動的にビルドとテストを行うプラクティスです。これにより、問題が早期に発見されます。
技術的詳細
元の CL 77050045
が追加しようとしたテスト test/fixedbugs/issue7525.go
は、Goコンパイラが自己参照的な配列のサイズ定義をどのように扱うかを検証するものでした。
Go言語の仕様では、配列の長さはコンパイル時に決定可能な定数式である必要があります。しかし、unsafe.Sizeof
, unsafe.Offsetof
, unsafe.Alignof
や、構造体のフィールドに対する len
, cap
の呼び出しは、コンパイル時にその値が確定しない、あるいは循環参照を引き起こす可能性があるため、配列のサイズとして使用することは通常許可されません。
issue7525.go
のテストコードは、以下のような構造体を定義していました。
var x struct {
a [unsafe.Sizeof(x.a)]int // ERROR "array bound|invalid array"
b [unsafe.Offsetof(x.b)]int // ERROR "array bound|invalid array"
c [unsafe.Alignof(x.c)]int // ERROR "array bound|invalid array"
d [len(x.d)]int // ERROR "array bound|invalid array"
e [cap(x.e)]int // ERROR "array bound|invalid array"
}
このコードは、x.a
のサイズを x.a
自身のサイズで定義しようとするなど、循環的な依存関係を持っています。Goコンパイラはこのような無効な配列のサイズ定義に対してエラーを報告するべきです。// ERROR "array bound|invalid array"
というコメントは、コンパイラが期待するエラーメッセージを示しています。
しかし、このテストコードが導入された結果、「すべてのビルドを破壊する」という事態が発生しました。これは、cmd/gc
(Goコンパイラ) がこの種の自己参照型配列の定義を処理する際に、コンパイラのクラッシュ、無限ループ、あるいは不正なコード生成といった深刻なバグを露呈した可能性が高いことを示唆しています。
考えられる原因としては、以下のようなものが挙げられます。
- コンパイラの無限ループまたはスタックオーバーフロー: 自己参照的な型定義を解決しようとする際に、コンパイラの型推論または型チェックロジックが無限ループに陥ったり、再帰が深くなりすぎてスタックオーバーフローを引き起こしたりした可能性があります。
- 不正なAST (Abstract Syntax Tree) 生成: コンパイラがこの特殊なケースのコードを解析する際に、内部的な抽象構文木が不正な状態になり、後続のコンパイルフェーズでクラッシュを引き起こした可能性があります。
- 未定義動作のトリガー:
unsafe
パッケージの使用と自己参照が組み合わさることで、コンパイラが想定していないエッジケースに遭遇し、未定義動作を引き起こした可能性があります。 - クロスコンパイル環境での問題: 特定のアーキテクチャやOSの組み合わせ(クロスコンパイル環境)で、この種のコードがコンパイラに問題を引き起こした可能性も考えられます。
このコミットは、問題の原因を特定して修正するのではなく、単に問題を引き起こしたテストコードを削除することで、ビルドを安定した状態に戻すことを目的としています。これは、Goのような大規模なプロジェクトでは、安定性を最優先し、問題の根本原因の調査と修正は別の機会に行うという一般的なプラクティスです。
コアとなるコードの変更箇所
このコミットのコアとなる変更は、単一のファイルの削除です。
test/fixedbugs/issue7525.go
が削除されました。
変更の差分は以下の通りです。
--- a/test/fixedbugs/issue7525.go
+++ /dev/null
@@ -1,19 +0,0 @@
-// errorcheck
-//
-// Copyright 2014 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.
-//
-// Issue 7525: self-referential array types.
-//
-// package main
-//
-// import "unsafe"
-//
-// var x struct {
-// a [unsafe.Sizeof(x.a)]int // ERROR "array bound|invalid array"
-// b [unsafe.Offsetof(x.b)]int // ERROR "array bound|invalid array"
-// c [unsafe.Alignof(x.c)]int // ERROR "array bound|invalid array"
-// d [len(x.d)]int // ERROR "array bound|invalid array"
-// e [cap(x.e)]int // ERROR "array bound|invalid array"
-// }
この差分は、ファイル test/fixedbugs/issue7525.go
の全行が削除されたことを示しています。
コアとなるコードの解説
このコミットには、新しいコードの追加や既存コードの修正は含まれていません。唯一の変更は、問題を引き起こしたテストファイル test/fixedbugs/issue7525.go
の削除です。
このファイルは、Goコンパイラが自己参照的な配列のサイズ定義を正しくエラーとして検出するかどうかを検証するためのテストケースでした。しかし、このテストケース自体がコンパイラのビルドプロセスを破壊したため、一時的に削除されました。
この削除は、問題の根本的な解決ではなく、ビルドの安定性を回復するための緊急措置です。将来的には、コンパイラのバグが修正された後、同様のテストケースが再導入される可能性があります。
関連リンク
- 元の変更 (CL 77050045): https://golang.org/cl/77050045
- この取り消し変更 (CL 77210043): https://golang.org/cl/77210043
参考にした情報源リンク
- Go言語の公式ドキュメント: https://golang.org/doc/
- Go言語の
unsafe
パッケージに関するドキュメント: https://pkg.go.dev/unsafe - Go言語の配列に関する仕様: https://go.dev/ref/spec#Array_types
- Go言語の
len
およびcap
関数に関する仕様: https://go.dev/ref/spec#Length_and_capacity - Goのコードレビュープロセスに関する情報 (Go Wikiなど): https://go.dev/wiki/CodeReview
- Goの継続的インテグレーションシステムに関する情報 (Go Wikiなど): https://go.dev/wiki/ContinuousIntegration
- GoのIssueトラッカー (Issue 7525に関する情報がある可能性): https://go.dev/issue
- Goのコミット履歴 (Gitリポジトリ): https://github.com/golang/go
- GoのChange List (CL) の検索: https://go-review.googlesource.com/