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

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

このコミットは、Go言語のテストスイートの一部である test/const1.go ファイルに対する変更です。具体的には、コンパイル時に発生するエラーメッセージの期待値を調整し、gccgo コンパイラが出力するエラーメッセージの形式に一致させることを目的としています。

コミット

commit 8b3df525a28c7aac6f8bc7e8186fe68f2c779737
Author: Ian Lance Taylor <iant@golang.org>
Date:   Thu Mar 19 17:33:28 2009 -0700

    Modify error regexps to match gccgo error messages.
    
    const1.go:23:13: error: integer constant overflow
    const1.go:25:13: error: integer constant overflow
    const1.go:26:14: error: integer constant overflow
    const1.go:27:18: error: integer constant overflow
    const1.go:28:19: error: integer constant overflow
    const1.go:29:16: error: integer constant overflow
    const1.go:29:25: error: integer constant overflow
    const1.go:30:13: error: integer constant overflow
    const1.go:33:14: error: integer constant overflow
    const1.go:34:14: error: integer constant overflow
    const1.go:36:22: error: integer constant overflow
    const1.go:37:7: error: integer constant overflow
    const1.go:38:8: error: integer constant overflow
    const1.go:39:7: error: integer constant overflow
    const1.go:40:7: error: integer constant overflow
    const1.go:41:8: error: integer constant overflow
    const1.go:44:23: error: integer constant overflow
    const1.go:46:13: error: integer constant overflow
    const1.go:47:24: error: integer constant overflow
    const1.go:48:24: error: integer constant overflow
    const1.go:49:22: error: integer constant overflow
    const1.go:51:23: error: integer constant overflow
    const1.go:52:19: error: division by zero
    const1.go:58:11: error: division by zero
    const1.go:43:17: error: integer constant overflow
    const1.go:45:13: error: integer constant overflow
    const1.go:55:19: error: floating point overflow
    const1.go:56:28: error: floating point overflow
    const1.go:57:11: error: floating point overflow
    const1.go:64:2: error: argument 0 has wrong type
    const1.go:65:2: error: argument 0 has wrong type
    const1.go:66:2: error: argument 0 has wrong type
    const1.go:68:2: error: argument 0 has wrong type
    const1.go:69:2: error: argument 0 has wrong type
    const1.go:70:4: error: floating point constant truncated to integer
    const1.go:72:2: error: argument 0 has wrong type
    const1.go:73:2: error: argument 0 has wrong type
    const1.go:74:2: error: argument 0 has wrong type
    
    R=rsc
    DELTA=34  (0 added, 0 deleted, 34 changed)
    OCL=26560
    CL=26560

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

https://github.com/golang/go/commit/8b3df525a28c7aac6f8bc7e8186fe68f2c779737

元コミット内容

このコミットの目的は、Go言語のテストスイートが gccgo コンパイラによって生成されるエラーメッセージと一致するように、正規表現(regexp)を修正することです。コミットメッセージには、const1.go ファイルで発生する可能性のある様々なエラー(整数定数のオーバーフロー、ゼロ除算、浮動小数点数のオーバーフロー、引数の型が間違っているなど)の例が示されており、これらが gccgo の出力形式に合わせられていることが示唆されています。

変更の背景

Go言語には、公式のコンパイラである gc(Go Compiler)と、GCC(GNU Compiler Collection)のフロントエンドとして開発された gccgo の2つの主要なコンパイラが存在します。Goのテストスイートは、言語仕様に準拠していることを確認するために、様々なコンパイラでテストが実行されることが一般的です。

このコミットが行われた2009年3月は、Go言語がまだ初期開発段階にあった時期です。この段階では、異なるコンパイラ実装間での挙動の差異や、エラーメッセージのフォーマットの不一致が発生することは珍しくありませんでした。特に、gccgo はGCCのインフラストラクチャを利用しているため、gc とは異なるエラー報告メカニズムを持つ可能性がありました。

test/const1.go のようなテストファイルは、コンパイル時に特定のエラーが発生することを期待し、そのエラーメッセージを正規表現でチェックすることで、コンパイラが正しくエラーを検出・報告しているかを確認します。しかし、gccgogc とは異なるエラーメッセージを出力した場合、テストが失敗してしまいます。このコミットは、テストの安定性を確保し、gccgo を含む複数のコンパイラでテストがパスするように、期待されるエラーメッセージの正規表現を調整する必要があったという背景があります。

前提知識の解説

Go言語のコンパイラ

  • gc (Go Compiler): Go言語の公式かつ主要なコンパイラです。Go言語自体で書かれており、高速なコンパイルと最適化が特徴です。
  • gccgo: GCCのフロントエンドとして実装されたGoコンパイラです。GCCのバックエンドを利用するため、GCCがサポートする多くのアーキテクチャでGoプログラムをコンパイルできます。gc とは異なるコード生成パスを持つため、生成されるバイナリの特性や、コンパイル時のエラーメッセージの形式が異なる場合があります。

Go言語のテストスイートとエラーメッセージのテスト

Go言語の標準ライブラリやコンパイラのテストスイートには、特定のコードがコンパイルエラーになることを期待し、そのエラーメッセージの内容を検証するテストが含まれています。これは、コンパイラが言語仕様に違反するコードを正しく拒否し、ユーザーに適切なフィードバックを提供していることを確認するために重要です。

これらのテストでは、Goソースコードのコメント内に // ERROR "regexp" のような形式で、期待されるエラーメッセージの正規表現を記述することがあります。コンパイラがコードを処理した際に、指定された正規表現に一致するエラーメッセージが出力されればテストは成功し、一致しなければ失敗します。

正規表現 (Regular Expression)

正規表現は、文字列のパターンを記述するための強力なツールです。このコミットでは、コンパイラが出力するエラーメッセージの文字列パターンを定義するために使用されています。例えば、"overflow" は「overflow」という文字列を含むエラーメッセージに一致し、"convert|wrong type" は「convert」または「wrong type」のいずれかの文字列を含むエラーメッセージに一致します。

技術的詳細

このコミットの技術的な核心は、Goコンパイラのテストフレームワークにおけるエラーメッセージの正規表現マッチングの調整にあります。

test/const1.go ファイルは、Go言語の定数に関する様々なコンパイル時エラー(例: 整数オーバーフロー、型変換エラー、ゼロ除算など)を意図的に引き起こすように設計されています。これらのエラーが発生した際に、Goのテストシステムは、ソースコードの該当行に記述された // ERROR "..." コメント内の正規表現と、コンパイラが出力した実際のエラーメッセージを比較します。

変更前は、gc コンパイラが生成するエラーメッセージの形式に合わせて正規表現が記述されていました。しかし、gccgo コンパイラが同じエラーに対して異なる、あるいはより簡潔なメッセージを出力した場合、既存の正規表現ではマッチせず、テストが失敗していました。

具体的には、以下の変更が行われています。

  1. "overflows" から "overflow" への変更:

    • 多くの整数定数オーバーフローのエラーメッセージで、期待される正規表現が "overflows" から "overflow" に変更されています。これは、gccgo がエラーメッセージの末尾に 's' を付けない形式で「overflow」を報告していたことを示唆しています。
    • 例: // ERROR "overflows" -> // ERROR "overflow"
  2. "convert" から "convert|wrong type" への変更:

    • 型変換に関するエラーメッセージで、期待される正規表現が "convert" から "convert|wrong type" に変更されています。これは、gccgo が型変換エラーを「convert」という単語ではなく、「wrong type」という表現で報告するケースがあったため、両方の可能性をカバーするように正規表現を拡張したものです。これにより、gcgccgo の両方でテストがパスするようになります。
    • 例: // ERROR "convert" -> // ERROR "convert|wrong type"

この変更は、Go言語のテストスイートが特定のコンパイラ実装に依存しすぎないようにするための重要なステップであり、異なるコンパイラ間での互換性を高めるための継続的な努力の一環です。

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

変更は test/const1.go ファイルのみです。

--- a/test/const1.go
+++ b/test/const1.go
@@ -24,56 +24,56 @@ const (
 )
 
 var (
-	a1 = Int8 * 100;	// ERROR "overflows"
+	a1 = Int8 * 100;	// ERROR "overflow"
 	a2 = Int8 * -1;	// OK
-	a3 = Int8 * 1000;	// ERROR "overflows"
-	a4 = Int8 * int8(1000);	// ERROR "overflows"
-	a5 = int8(Int8 * 1000);	// ERROR "overflows"
-	a6 = int8(Int8 * int8(1000));	// ERROR "overflows"
-	a7 = Int8 - 2*Int8 - 2*Int8;	// ERROR "overflows"
-	a8 = Int8 * Const / 100;	// ERROR "overflows"
+	a3 = Int8 * 1000;	// ERROR "overflow"
+	a4 = Int8 * int8(1000);	// ERROR "overflow"
+	a5 = int8(Int8 * 1000);	// ERROR "overflow"
+	a6 = int8(Int8 * int8(1000));	// ERROR "overflow"
+	a7 = Int8 - 2*Int8 - 2*Int8;	// ERROR "overflow"
+	a8 = Int8 * Const / 100;	// ERROR "overflow"
 	a9 = Int8 * (Const / 100);	// OK
 
-	b1 = Uint8 * Uint8;	// ERROR "overflows"
-	b2 = Uint8 * -1;	// ERROR "overflows"
+	b1 = Uint8 * Uint8;	// ERROR "overflow"
+	b2 = Uint8 * -1;	// ERROR "overflow"
 	b3 = Uint8 - Uint8;	// OK
-	b4 = Uint8 - Uint8 - Uint8;	// ERROR "overflows"
-	b5 = uint8(^0);	// ERROR "overflows"
-	b6 = ^uint8(0);	// ERROR "overflows"
-	b7 = uint8(Minus1);	// ERROR "overflows"
-	b8 = uint8(int8(-1));	// ERROR "overflows"
-	b8a = uint8(-1);	// ERROR "overflows"
+	b4 = Uint8 - Uint8 - Uint8;	// ERROR "overflow"
+	b5 = uint8(^0);	// ERROR "overflow"
+	b6 = ^uint8(0);	// ERROR "overflow"
+	b7 = uint8(Minus1);	// ERROR "overflow"
+	b8 = uint8(int8(-1));	// ERROR "overflow"
+	b8a = uint8(-1);	// ERROR "overflow"
 	b9 byte = (1<<10) >> 8;	// OK
-	b10 byte = (1<<10);	// ERROR "overflows"
-	b11 byte = (byte(1)<<10) >> 8;	// ERROR "overflows"
-	b12 byte = 1000;	// ERROR "overflows"
-	b13 byte = byte(1000);	// ERROR "overflows"
-	b14 byte = byte(100) * byte(100);	// ERROR "overflows"
-	b15 byte = byte(100) * 100;	// ERROR "overflows"
-	b16 byte = byte(0) * 1000;	// ERROR "overflows"
+	b10 byte = (1<<10);	// ERROR "overflow"
+	b11 byte = (byte(1)<<10) >> 8;	// ERROR "overflow"
+	b12 byte = 1000;	// ERROR "overflow"
+	b13 byte = byte(1000);	// ERROR "overflow"
+	b14 byte = byte(100) * byte(100);	// ERROR "overflow"
+	b15 byte = byte(100) * 100;	// ERROR "overflow"
+	b16 byte = byte(0) * 1000;	// ERROR "overflow"
 	b16a byte = 0 * 1000;	// OK
-	b17 byte = byte(0) * byte(1000);	// ERROR "overflows"
+	b17 byte = byte(0) * byte(1000);	// ERROR "overflow"
 	b18 byte = Uint8/0;	// ERROR "division by zero"
 
 	c1 float64 = Big;
-	c2 float64 = Big*Big;	// ERROR "overflows"
-	c3 float64 = float64(Big)*Big;	// ERROR "overflows"
-	c4 = Big*Big;	// ERROR "overflows"
+	c2 float64 = Big*Big;	// ERROR "overflow"
+	c3 float64 = float64(Big)*Big;	// ERROR "overflow"
+	c4 = Big*Big;	// ERROR "overflow"
 	c5 = Big/0;	// ERROR "division by zero"
 )
 
 func f(int);
 
 func main() {
-	f(Int8);	// ERROR "convert"
-	f(Minus1);	// ERROR "convert"
-	f(Uint8);	// ERROR "convert"
+	f(Int8);	// ERROR "convert|wrong type"
+	f(Minus1);	// ERROR "convert|wrong type"
+	f(Uint8);	// ERROR "convert|wrong type"
 	f(Const);	// OK
-	f(Float32);	// ERROR "convert"
-	f(Float);	// ERROR "convert"
+	f(Float32);	// ERROR "convert|wrong type"
+	f(Float);	// ERROR "convert|wrong type"
 	f(ConstFloat);	// ERROR "truncate"
 	f(ConstFloat - 0.5);	// OK
-	f(Big);	// ERROR "convert"
-	f(String);	// ERROR "convert"
-	f(Bool);	// ERROR "convert"
+	f(Big);	// ERROR "convert|wrong type"
+	f(String);	// ERROR "convert|wrong type"
+	f(Bool);	// ERROR "convert|wrong type"
 }

コアとなるコードの解説

このコミットは、test/const1.go ファイル内のコメント行を修正しています。これらのコメントは、Goのテストフレームワークがコンパイラのエラー出力を検証するために使用する正規表現を定義しています。

具体的には、以下の2種類の変更が行われています。

  1. "overflows" から "overflow" への変更:

    • a1, a3 から a8 までの変数宣言、b1, b2, b4 から b8a までの変数宣言、b10 から b17 までの変数宣言、および c2 から c4 までの変数宣言に関連するエラーコメントが修正されています。
    • これらの行は、整数定数のオーバーフローや浮動小数点数のオーバーフローなど、数値計算におけるオーバーフローエラーを意図的に発生させています。
    • 元の正規表現 "overflows" は、gc コンパイラが「integer constant overflows」のようなメッセージを出力する際にマッチするように設計されていました。しかし、gccgo が「integer constant overflow」のように 's' を含まない形式でエラーを報告する場合、テストが失敗します。
    • この変更により、正規表現をより一般的な "overflow" にすることで、両方のコンパイラのエラーメッセージにマッチするようになり、テストの互換性が向上しました。
  2. "convert" から "convert|wrong type" への変更:

    • main 関数内の f 関数呼び出しに関連するエラーコメントが修正されています。
    • これらの行は、f 関数が int 型の引数を期待しているにもかかわらず、異なる型の定数(例: Int8, Minus1, Uint8, Float32, Float, Big, String, Bool)を渡すことで、型変換エラーを意図的に発生させています。
    • 元の正規表現 "convert" は、gc コンパイラが「cannot convert ...」のようなメッセージを出力する際にマッチするように設計されていました。
    • しかし、gccgo がこれらの型不一致エラーを「argument 0 has wrong type」のようなメッセージで報告する可能性があったため、正規表現を "convert|wrong type" に拡張しました。これにより、「convert」または「wrong type」のいずれかの文字列を含むエラーメッセージにマッチするようになり、gccgo の出力にも対応できるようになりました。

これらの変更は、Go言語のテストスイートが特定のコンパイラの実装詳細に過度に依存することなく、言語仕様に準拠していることをより堅牢に検証できるようにするためのものです。

関連リンク

参考にした情報源リンク