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

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

このコミットは、Go言語のコンパイラが特定の不正なコードパターンに対して適切にエラーを報告することを確認するための、2つの新しいテストケースを追加します。具体的には、string型とnilの比較、およびpackage宣言の欠如という、Go言語の基本的な型システムと構文規則に関するエラーを検証します。これらのテストは、コンパイラの堅牢性と、言語仕様への準拠を保証するために重要です。

コミット

commit ec94a8cfc9d3b553700fe275a6b01087bb3541c9
Author: Rob Pike <r@golang.org>
Date:   Tue Jun 17 10:56:28 2008 -0700

    add two more tests
    
    SVN=123143

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

https://github.com/golang/go/commit/ec94a8cfc9d3b553700fe275a6b01087bb3541c9

元コミット内容

add two more tests
    
SVN=123143

変更の背景

このコミットは、Go言語の初期開発段階において、コンパイラのバグ検出能力とエラー報告の正確性を向上させるために行われました。特に、Go言語の型システムと構文規則がまだ確立されつつある時期に、開発者が陥りやすい誤りをコンパイラが確実に捕捉できることを保証することが目的でした。

bug049.goで追加されたテストは、string型が値型であり、nilと比較できないというGoの基本的な特性を検証します。CやJavaのような言語ではポインタや参照型がnilになり得ますが、Goのstring型はプリミティブな値型であり、nilという概念は適用されません。このテストは、このような誤った比較がコンパイル時に「stringpool: not string」という致命的なエラーとして検出されることを確認します。

bug050.goで追加されたテストは、Goのソースファイルが必ずpackage宣言で始まるという基本的な構文規則を検証します。Goのプログラムはパッケージに属する必要があり、ソースファイルの先頭にpackage宣言を記述することは必須です。このテストは、この宣言が欠如している場合にコンパイラが「package statement must be first」というエラーを適切に報告することを確認します。

これらのテストの追加は、Goコンパイラの堅牢性を高め、開発者が言語の規則に違反するコードを記述した際に、明確で役立つエラーメッセージを提供するための重要なステップでした。

前提知識の解説

Go言語の型システムとnil

Go言語において、nilはポインタ、インターフェース、マップ、スライス、チャネルなどの参照型にのみ適用される特別な値です。これらの型が何も指していない状態、または初期化されていない状態を示します。しかし、intboolstringなどのプリミティブな値型にはnilという概念は存在しません。これらの型は常に何らかの値を持ち、そのゼロ値(例: stringの場合は空文字列"")で初期化されます。したがって、string型の変数とnilを直接比較しようとすると、コンパイルエラーが発生します。

Go言語のパッケージ宣言

Go言語のソースファイルは、必ずpackage宣言で始まります。これは、そのファイルがどのパッケージに属するかをコンパイラに伝えるためのものです。実行可能なプログラム(コマンド)を作成する場合、通常はpackage mainと宣言し、main関数を定義します。ライブラリを作成する場合は、そのライブラリの名前をパッケージ名として宣言します。package宣言はソースファイルの最初の非コメント行である必要があり、これが欠如しているとコンパイルエラーになります。

errchkディレクティブ

Goのテストフレームワークの一部として、testディレクトリ内のテストファイルには特別なコメントディレクティブが使用されることがあります。// errchk $G $D/$F.goのような行は、そのテストファイルがコンパイル時に特定のエラーを生成することを期待していることを示します。$GはGoコンパイラ、$Dは現在のディレクトリ、$F.goは現在のファイル名を表すプレースホルダーです。テスト実行時に、指定されたエラーが実際に発生するかどうかが検証されます。これにより、コンパイラが意図したエラーを正しく報告し続けることを保証する回帰テストが可能になります。

test/golden.outファイル

test/golden.outファイルは、Goのテストスイートにおいて、特定のテストケースの期待される出力(特にエラーメッセージや標準出力)を記録するために使用される「ゴールデンファイル」の一種です。テストが実行されると、その出力がこのファイルに記録された期待される出力と比較されます。もし出力が一致しない場合、テストは失敗とみなされます。これにより、コンパイラやツールの出力が将来の変更によって意図せず変更されることを防ぎ、回帰テストの重要な要素となります。

技術的詳細

このコミットは、Goコンパイラのセマンティックチェックと構文解析の正確性を検証するためのものです。

test/bugs/bug049.go

このファイルは、string型の引数sを受け取るatom関数を定義しています。関数内でs == nilという比較が行われています。Go言語の仕様では、string型は値型であり、nilと比較することはできません。このコードは、コンパイル時に型不一致のエラーを引き起こすことが期待されます。errchkディレクティブは、コンパイラが「stringpool: not string」というエラーメッセージを生成することを検証します。これは、コンパイラが文字列プール(または文字列リテラル)に関連する内部的な型チェックで、nilが文字列ではないことを検出したことを示唆しています。

test/bugs/bug050.go

このファイルは、package main宣言を欠いたままfunc main() {}を定義しています。Goのソースファイルは必ずpackage宣言で始まる必要があるため、このファイルは構文エラーを引き起こすことが期待されます。errchkディレクティブは、コンパイラが「package statement must be first」というエラーと、それに続く「syntax error」を報告することを検証します。これは、コンパイラの字句解析器と構文解析器が、ファイルの先頭にpackage宣言がないことを正しく識別し、適切なエラーメッセージを生成することを確認します。

test/golden.out

このファイルへの変更は、bug049.gobug050.goのテストが生成する期待されるエラー出力をgolden.outに追加するものです。これにより、これらのテストが将来のコンパイラの変更によっても引き続き同じエラーを生成し、意図しない動作変更がないことを保証します。

  • bug049.goのエントリは、bugs/bug049.go:6: fatal error: stringpool: not stringというエラーメッセージと、そのエラーが致命的であることを示すBUG: fatal errorを含みます。
  • bug050.goのエントリは、bugs/bug050.go:3: package statement must be firstsys.6:1 bugs/bug050.go:2: syntax errorというエラーメッセージ、そしてBUG: segfaultという記述を含みます。BUG: segfaultは、この特定のケースでコンパイラがセグメンテーション違反を起こす可能性があるという、当時の既知の問題を示唆している可能性があります。これは、エラー処理がまだ完全ではなかった初期段階のコンパイラの挙動を記録していると考えられます。

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

test/bugs/bug049.go

// errchk $G $D/$F.go

// 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 atom(s string) {
	if s == nil { // ここでstringとnilの比較が行われる
		return;
	}
}

/*
bug047.go:4: fatal error: stringpool: not string
*/

test/bugs/bug050.go

// errchk $G $D/$F.go

// 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.

func main() { // package main宣言が欠如している
}

test/golden.out

--- a/test/golden.out
+++ b/test/golden.out
@@ -242,6 +242,15 @@ bugs/bug048.go:7: illegal types for operand: CONV
 bugs/bug048.go:8: syntax error
 BUG: known to fail incorrectly
 
+=========== bugs/bug049.go
+bugs/bug049.go:6: fatal error: stringpool: not string
+BUG: fatal error
+\n
+=========== bugs/bug050.go
+bugs/bug050.go:3: package statement must be first
+sys.6:1 bugs/bug050.go:2: syntax error
+BUG: segfault
+\n
 =========== fixedbugs/bug000.go
 
 =========== fixedbugs/bug001.go

コアとなるコードの解説

test/bugs/bug049.goの解説

このテストファイルは、Go言語の型システムにおける重要な制約を検証します。func atom(s string)関数内でif s == nilという条件が記述されていますが、Goにおいてstring型は値型であり、nilという概念は適用されません。nilはポインタ、インターフェース、スライス、マップ、チャネルなどの参照型にのみ使用されます。

このコードは、コンパイル時に型不一致のエラーを引き起こすことが意図されています。// errchk $G $D/$F.goという行は、Goコンパイラ($G)がこのファイルをコンパイルする際に、特定のエラーを生成することを期待していることを示します。コメントブロック内のbug047.go:4: fatal error: stringpool: not stringは、このテストが期待するエラーメッセージのパターンです。これは、コンパイラが文字列の内部表現(文字列プール)に関連するチェックで、nilが有効な文字列ではないことを検出したことを示唆しています。このテストは、Goコンパイラが言語の型安全性を強制し、不正な型操作を早期に検出できることを保証します。

test/bugs/bug050.goの解説

このテストファイルは、Goソースファイルの基本的な構造に関する規則を検証します。Goのソースファイルは、必ずpackage宣言で始まらなければなりません。しかし、このファイルにはpackage mainのようなパッケージ宣言が欠如しています。

// errchk $G $D/$F.goディレクティブは、コンパイラがこのファイルをコンパイルする際にエラーを生成することを期待していることを示します。test/golden.outに追加されたエントリが示すように、期待されるエラーメッセージは「package statement must be first」と「syntax error」です。これは、コンパイラの字句解析器と構文解析器が、ファイルの先頭にpackage宣言がないことを正しく識別し、適切なエラーメッセージを生成することを確認します。このテストは、Goコンパイラが言語の構文規則を厳密に適用し、基本的な構造の誤りを確実に報告できることを保証します。

test/golden.outの解説

test/golden.outファイルへの変更は、上記2つの新しいテストケースの期待されるコンパイラ出力(エラーメッセージ)を記録するものです。これにより、これらのテストが将来のコンパイラの変更によっても引き続き同じエラーを生成し、意図しない回帰が発生しないことを保証します。

  • bug049.goのエントリは、bugs/bug049.go:6: fatal error: stringpool: not stringというエラーメッセージと、そのエラーが致命的であることを示すBUG: fatal errorを含みます。これは、stringnilの比較がコンパイル時に致命的なエラーとして扱われるべきであることを示しています。
  • bug050.goのエントリは、bugs/bug050.go:3: package statement must be firstsys.6:1 bugs/bug050.go:2: syntax errorというエラーメッセージを含みます。さらにBUG: segfaultという記述があります。これは、当時のGoコンパイラがpackage宣言の欠如という特定の構文エラーに遭遇した際に、セグメンテーション違反(プログラムのクラッシュ)を引き起こす可能性があったという、既知のバグまたは不安定な挙動を記録していると考えられます。このgolden.outへの追加は、そのバグが修正された後も、同様の入力でコンパイラがクラッシュしないことを確認するための回帰テストとして機能します。

これらの変更は、Goコンパイラの品質と安定性を向上させるための、初期段階における重要なテストインフラの整備を示しています。

関連リンク

参考にした情報源リンク