Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

[インデックス 197] ファイルの概要

このコミットは、Go言語の初期開発段階において、コンパイラまたはランタイムの既知のバグを特定し追跡するために新しいテストケース bug055.go を追加したものです。このテストは、特定のGo言語の構文要素の組み合わせが、当時のコンパイラで正しく処理されない問題(おそらく型宣言の重複に関連する)を浮き彫りにすることを目的としていました。

コミット

add new test bug055

SVN=123431

GitHub上でのコミットページへのリンク

https://github.com/golang/go/commit/74aa77fbd477ae68b487a9962d847b822e1738ee

元コミット内容

commit 74aa77fbd477ae68b487a9962d847b822e1738ee
Author: Rob Pike <r@golang.org>
Date:   Wed Jun 18 14:17:24 2008 -0700

    add new test bug055
    
    SVN=123431
---
 test/bugs/bug055.go | 21 +++++++++++++++++++++
 test/golden.out     |  4 ++++
 2 files changed, 25 insertions(+)

diff --git a/test/bugs/bug055.go b/test/bugs/bug055.go
new file mode 100644
index 0000000000..8812efec8f
--- /dev/null
+++ b/test/bugs/bug055.go
@@ -0,0 +1,21 @@
+// $G $D/$F.go && $L $F.$A && ./$A.out
+//
+// Copyright 2009 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 main
+
+func main() {
+	var i int
+	var j int
+	if true {}
+	{ return }
+	i = 0
+	if true {} else i++
+	type s struct {};
+	i = 0
+	type s int
+	var k = func (a int) int { return a+1 }(3);
+ro:
+}
diff --git a/test/golden.out b/test/golden.out
index 67fb83f57b..3fb300d907 100644
--- a/test/golden.out
+++ b/test/golden.out
@@ -261,6 +261,10 @@ BUG: len should not be a keyword
 bugs/bug054.go:22: fatal error: agen: unknown op CALLMETH u(1) l(165) <Element>I{}\n BUG: known to fail incorrectly
 
+=========== bugs/bug055.go
+bug055.go:1: fatal error: cant open: bug055.go
+BUG: known to fail incorrectly
+
 =========== fixedbugs/bug000.go
 
 =========== fixedbugs/bug001.go

変更の背景

このコミットは、Go言語の非常に初期の段階(2008年6月)に行われました。当時のGoコンパイラやランタイムはまだ開発途上にあり、多くのバグや未実装の機能が存在していました。このような状況下で、開発チームは test/bugs ディレクトリに、既知のコンパイラやランタイムの問題を再現し、その修正を追跡するためのテストケースを追加していました。

bug055.go の追加は、特定のGo言語の構文パターンが当時のコンパイラで正しく処理されない、あるいは予期せぬエラーを引き起こす既知のバグが存在したことを示唆しています。test/golden.out ファイルに「BUG: known to fail incorrectly」という記述があることから、このテストはバグが修正されるまで失敗することが意図されており、その進捗を監視するためのものであったことがわかります。

特に、bug055.go 内の type s struct {}; の後に type s int と同じ名前 s で型を再宣言している箇所は、Go言語のスコープ規則や型システムにおける潜在的なバグをテストしている可能性が高いです。Go言語では、同じスコープ内で同じ名前の型を複数回宣言することは通常許可されていません。初期のコンパイラがこのようなケースを適切に検出・処理できなかった可能性があります。

前提知識の解説

  • Go言語の初期開発: Go言語は2007年にGoogleで設計が始まり、2009年にオープンソースとして公開されました。このコミットは公開前の非常に初期の段階のものであり、言語仕様やコンパイラの実装がまだ固まっていない時期でした。
  • コンパイラのバグ: コンパイラはソースコードを機械語に変換するソフトウェアです。コンパイラのバグは、正当なコードを誤ってエラーと判断したり、誤った機械語を生成したり、クラッシュしたりする原因となります。
  • テスト駆動開発 (TDD) とバグ追跡: ソフトウェア開発において、バグを再現するテストケースを作成することは、バグの特定、修正、そして将来的な回帰を防ぐ上で非常に重要です。test/bugs ディレクトリは、このようなバグ追跡のためのテストを格納する一般的なパターンです。
  • Go言語の基本構文:
    • 変数宣言: var i int は整数型の変数 i を宣言します。
    • if ステートメント: if true {} のように、条件式とそれに続くコードブロックで構成されます。Goでは、空のブロックも有効な構文です。
    • return ステートメント: 関数から戻るために使用されます。{ return } のように、ブロック内で単独で使用することも可能です。
    • 型宣言: type s struct {} は構造体型 s を定義します。type s int は整数型を基底とする新しい型 s を定義します。Go言語では、同じスコープ内で同じ名前の型を複数回宣言することはできません。
    • 関数リテラルと即時実行: func (a int) int { return a+1 }(3) は、その場で定義され、すぐに実行される匿名関数です。
    • ラベル: ro: のように、goto ステートメントのターゲットとして使用できるラベルです。

技術的詳細

bug055.go は、Go言語のコンパイラが様々な構文要素をどのように処理するかをテストするための、意図的に多様なコードスニペットを含むファイルです。このテストの主な目的は、コンパイラのパーサー、セマンティックアナライザー、または型チェッカーにおける既知のバグを露呈させることでした。

特に注目すべきは、以下のコード行です。

	type s struct {};
	i = 0
	type s int

ここで、s という名前の型が最初に空の構造体として宣言され、その数行後に int 型のエイリアスとして再度宣言されています。Go言語の仕様では、同じスコープ内で同じ名前の識別子(変数、関数、型など)を複数回宣言することは許可されていません。これはコンパイルエラーとなるべき挙動です。

このコミットが2008年に行われたことを考えると、当時のGoコンパイラはまだ初期段階であり、このような型名の重複宣言のようなエッジケースを適切に検出できなかったか、あるいは誤ったエラーを生成していた可能性があります。bug055.go は、この特定のシナリオがコンパイラによってどのように扱われるかを検証し、バグが修正されたことを確認するためのリグレッションテストとして機能しました。

test/golden.out に記録された「fatal error: cant open: bug055.go」というメッセージは、初期のテスト実行環境やコンパイラの挙動による一時的なエラーである可能性があり、このテストが本来意図していたバグとは直接関係ないかもしれません。より重要なのは、その後に続く「BUG: known to fail incorrectly」という記述であり、これはこのテストが特定の既知のバグのために追加され、そのバグがまだ修正されていないことを明確に示しています。

このテストケースは、コンパイラが以下の要素を正しく処理できるかを検証する目的も持っていたと考えられます。

  • 空の if ブロックや空のコードブロック。
  • ブロック内での return ステートメント。
  • if-else 構造における空の if ブロック。
  • 関数リテラルの定義と即時実行。
  • ラベルの定義。

これらの要素は、コンパイラの構文解析器が複雑なコード構造を正しく解釈できるかどうかのテストポイントとなります。

コアとなるコードの変更箇所

このコミットによって追加または変更された主要なファイルは以下の通りです。

  • test/bugs/bug055.go: 新しく追加されたテストケースファイル。
  • test/golden.out: テスト結果のログファイルで、bug055.go のテスト結果が追記されています。

test/bugs/bug055.go の内容

// $G $D/$F.go && $L $F.$A && ./$A.out
//
// Copyright 2009 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 main

func main() {
	var i int
	var j int
	if true {}
	{ return }
	i = 0
	if true {} else i++
	type s struct {};
	i = 0
	type s int
	var k = func (a int) int { return a+1 }(3);
ro:
}

test/golden.out の変更箇所

--- a/test/golden.out
+++ b/test/golden.out
@@ -261,6 +261,10 @@ BUG: len should not be a keyword
 bugs/bug054.go:22: fatal error: agen: unknown op CALLMETH u(1) l(165) <Element>I{}\n BUG: known to fail incorrectly
 
+=========== bugs/bug055.go
+bug055.go:1: fatal error: cant open: bug055.go
+BUG: known to fail incorrectly
+
 =========== fixedbugs/bug000.go
 
 =========== fixedbugs/bug001.go

コアとなるコードの解説

test/bugs/bug055.go

このファイルは、main パッケージに属する main 関数のみで構成されています。関数内には、Go言語の様々な基本的な構文要素が意図的に配置されています。

  1. var i intvar j int: 整数型変数の宣言。
  2. if true {}: 条件が常に真である空の if ブロック。コンパイラが空のブロックを正しく処理できるかをテストします。
  3. { return }: 独立したコードブロック内での return ステートメント。Goでは、return は関数の実行を終了させます。この構文が正しく解析されるかをテストします。
  4. i = 0: 変数への代入。
  5. if true {} else i++: 空の if ブロックと else 節を持つ if-else ステートメント。これもコンパイラの構文解析能力をテストします。
  6. type s struct {};: s という名前の空の構造体型を宣言します。
  7. i = 0: 再び変数への代入。
  8. type s int: ここが最も重要な箇所です。 直前に s という名前の構造体型が宣言されているにもかかわらず、ここで s という名前で整数型を基底とする新しい型を再宣言しています。Go言語の現在の仕様では、これはコンパイルエラーとなるべきです。このテストは、初期のコンパイラがこの重複宣言をどのように扱うか、つまりエラーを正しく検出できるか、あるいはクラッシュするかを検証するために設計されたと考えられます。
  9. var k = func (a int) int { return a+1 }(3);: 匿名関数(関数リテラル)を定義し、すぐに引数 3 で実行し、その結果を変数 k に代入しています。これは、関数リテラルと即時実行の構文解析をテストします。
  10. ro:: ro というラベルを定義しています。これは goto ステートメントのターゲットとして使用できます。

このテストケース全体は、Goコンパイラのパーサー、セマンティックアナライザー、および型チェッカーが、これらの多様な、時にはエッジケースとなる構文を正しく処理できるかを検証するためのものです。特に型 s の重複宣言は、当時のコンパイラの型システムにおける既知の欠陥を狙ったものと推測されます。

test/golden.out

このファイルは、Goテストスイートの実行結果を記録するものです。このコミットでは、bug055.go のテスト結果が追記されています。

  • =========== bugs/bug055.go: bug055.go のテスト結果の開始を示します。
  • bug055.go:1: fatal error: cant open: bug055.go: これは、テスト実行時にファイルを開くことができなかったというエラーメッセージです。これは、テスト環境のセットアップの問題か、あるいはコンパイラが非常に早い段階でクラッシュしたために発生した一時的なメッセージである可能性があります。このメッセージ自体が bug055 がテストしようとしていた本来のバグではないと考えられます。
  • BUG: known to fail incorrectly: この行が最も重要です。これは、bug055.go がテストしているバグがまだ修正されておらず、テストが意図的に失敗することが期待されていることを明確に示しています。これは、開発チームがこのバグを認識しており、その修正に取り組んでいる、または将来的に取り組む予定であることを意味します。

関連リンク

Web検索では、この特定のコミットに関する追加の関連リンクは見つかりませんでした。

参考にした情報源リンク