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

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

このコミットは、Go言語のテストスイートにおけるエラーメッセージのマッチングロジックを更新するものです。具体的には、test/const6.gotest/fixedbugs/issue4085a.go のテストファイルにおいて、期待されるエラーメッセージのパターンに gccgo コンパイラが出力する可能性のある代替メッセージを追加しています。これにより、Goの公式コンパイラ(gc)と gccgo の両方でテストが正しくパスするように、エラーメッセージの柔軟性を高めています。

コミット

  • Author: Rémy Oudompheng oudomphe@phare.normalesup.org
  • Date: Wed Jun 26 18:05:02 2013 +0200
  • Original Commit Message:
    test: match gccgo error strings.
    
    R=golang-dev, bradfitz
    CC=golang-dev
    https://golang.org/cl/10468043
    

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

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

元コミット内容

test: match gccgo error strings.

R=golang-dev, bradfitz
CC=golang-dev
https://golang.org/cl/10468043

変更の背景

Go言語には、公式のコンパイラである gc(Go Compiler)の他に、GCC(GNU Compiler Collection)をバックエンドとして利用する gccgo という別のコンパイラ実装が存在します。これらのコンパイラは、Go言語の仕様に準拠してコードをコンパイルしますが、エラーメッセージの出力形式や文言が異なる場合があります。

Goのテストスイートでは、特定のコードがコンパイルエラーを引き起こすことを期待し、そのエラーメッセージの内容を正規表現でマッチングすることでテストの合否を判定する仕組みがあります。しかし、gcgccgo のエラーメッセージが完全に一致しない場合、一方のコンパイラではテストが成功しても、もう一方ではエラーメッセージの不一致によりテストが失敗するという問題が発生します。

このコミットの背景には、gccgo が出力するエラーメッセージが gc のそれと異なるケースがあり、既存のテストが gccgo で失敗していたという状況があります。この問題を解決し、両方のコンパイラでテストスイートが安定して動作するようにするために、エラーメッセージのマッチングパターンに gccgo の出力する代替メッセージを追加する必要がありました。

前提知識の解説

Go言語の型システムと定数式

Go言語は静的型付け言語であり、変数の型はコンパイル時に決定されます。型の一致は厳密にチェックされ、異なる型の値を比較したり、演算したりする際には型変換が必要となる場合があります。 定数式(constant expression)は、コンパイル時にその値が決定される式です。Goでは、数値、真偽値、文字列などのリテラルや、それらを用いた演算結果が定数式となります。定数式は型を持たない「untyped constant」として扱われることがあり、文脈に応じて適切な型に変換されます。しかし、型が明確に異なる定数間の比較や演算は、コンパイルエラーとなることがあります。

make 関数

make 関数は、Go言語においてスライス(slice)、マップ(map)、チャネル(channel)といった組み込みの参照型を初期化するために使用されます。

  • スライスの場合: make([]Type, len, cap) の形式で、要素の型、初期の長さ(len)、容量(cap)を指定します。lencap は非負の整数である必要があります。
  • マップの場合: make(map[KeyType]ValueType, initialCapacity) の形式で、キーと値の型、初期容量を指定します。
  • チャネルの場合: make(chan Type, bufferCapacity) の形式で、チャネルで送受信する要素の型、バッファ容量を指定します。

make 関数の引数に無効な値(例: 負の長さ、非整数値、容量より大きい長さ)が渡された場合、コンパイルエラーとなります。

Goのテストにおけるエラーメッセージのマッチング

Go言語のテストフレームワークでは、go test コマンドを使用してテストを実行します。特定のテストケースでは、意図的にコンパイルエラーを発生させ、そのエラーメッセージが期待通りであることを確認することがあります。これは、コンパイラが特定の不正なコードに対して正しいエラーを報告するかどうかを検証するために重要です。

Goのテストファイルでは、// ERROR "pattern" のようなコメントをコード行の末尾に記述することで、その行がコンパイルエラーを引き起こし、かつエラーメッセージが指定された正規表現パターンにマッチすることを期待するテストを記述できます。この機能は、コンパイラの挙動を詳細にテストするために広く利用されています。

gcgccgo

  • gc: Go言語の公式コンパイラであり、Goのソースコードをネイティブバイナリにコンパイルします。Go言語のツールチェインの一部として提供され、Go開発の標準的な環境です。
  • gccgo: GCC(GNU Compiler Collection)をバックエンドとして利用するGo言語のコンパイラです。gc とは異なる実装であり、GCCの最適化やコード生成の恩恵を受けることができます。しかし、エラーメッセージの生成ロジックや内部的な型表現の違いにより、gc とは異なるエラーメッセージを出力する場合があります。

技術的詳細

このコミットの技術的詳細は、Goコンパイラ(gc)と gccgo のエラーメッセージの差異を吸収し、テストの互換性を確保することにあります。

Goのテストスイートでは、// ERROR "pattern" というディレクティブを使用して、特定のコード行がコンパイルエラーを発生させ、そのエラーメッセージが指定された正規表現パターンにマッチすることを検証します。このパターンは、Goコンパイラ gc が出力するエラーメッセージを想定して記述されていることが多いです。

しかし、gccgogc とは独立したコンパイラ実装であるため、同じコンパイルエラーであっても、出力されるエラーメッセージの文言が異なることがあります。例えば、型不一致のエラーに対して gc が "mismatched types" と出力するのに対し、gccgo は "incompatible types" と出力する可能性があります。同様に、make 関数の引数に関するエラーでも、"constant 0.5 truncated to integer" と "non-integer len argument" のように、表現が異なることがあります。

このコミットでは、既存の // ERROR ディレクティブのパターンに、| (OR演算子) を用いて gccgo が出力する可能性のある代替エラーメッセージを追加しています。これにより、テスト実行時に gcgccgo のどちらのコンパイラが使用されても、期待されるエラーメッセージのいずれかにマッチすればテストが成功するようになります。

具体的には、以下のエラーメッセージパターンが更新されています。

  1. 型不一致のエラー:

    • 変更前: ERROR "mismatched types"
    • 変更後: ERROR "mismatched types|incompatible types"
    • これは、c1 == c2 のような異なる型の定数間の比較や、c1 && c2 のような真偽値以外の型に対する論理演算で発生するエラーに対応しています。gc は "mismatched types" を、gccgo は "incompatible types" を出力する可能性があります。
  2. make 関数の引数に関するエラー:

    • 変更前: ERROR "constant 0.5 truncated to integer"
    • 変更後: ERROR "constant 0.5 truncated to integer|non-integer len argument"
    • これは、make(T, 0.5) のように make 関数の len 引数に浮動小数点数が渡された場合に発生するエラーに対応しています。gc は「定数が整数に切り捨てられた」というメッセージを、gccgo は「非整数型のlen引数」というメッセージを出力する可能性があります。

この変更は、Go言語のテストスイートの堅牢性を高め、異なるコンパイラ実装間での互換性を維持するために重要な修正です。これにより、Go言語の進化と同時に、その代替コンパイラも適切にテストされ、Go言語の仕様への準拠が保証されます。

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

diff --git a/test/const6.go b/test/const6.go
index c04435db63..c005ac3696 100644
--- a/test/const6.go
+++ b/test/const6.go
@@ -19,12 +19,12 @@ var (
 	c4 mybool = c2 == (1 < 2)
 	c5 mybool = 1 < 2
 	c6 mybool1 = x < y
-	c7 = c1 == c2 // ERROR "mismatched types"
-	c8 = c2 == c6 // ERROR "mismatched types"
-	c9 = c1 == c6 // ERROR "mismatched types"
+	c7 = c1 == c2 // ERROR "mismatched types|incompatible types"
+	c8 = c2 == c6 // ERROR "mismatched types|incompatible types"
+	c9 = c1 == c6 // ERROR "mismatched types|incompatible types"
 	_ = c2 && (x < y)
 	_ = c2 && (1 < 2)
-	_ = c1 && c2 // ERROR "mismatched types"
-	_ = c2 && c6 // ERROR "mismatched types"
-	_ = c1 && c6 // ERROR "mismatched types"
+	_ = c1 && c2 // ERROR "mismatched types|incompatible types"
+	_ = c2 && c6 // ERROR "mismatched types|incompatible types"
+	_ = c1 && c6 // ERROR "mismatched types|incompatible types"
 )
diff --git a/test/fixedbugs/issue4085a.go b/test/fixedbugs/issue4085a.go
index 8a52b268ff..089637d86b 100644
--- a/test/fixedbugs/issue4085a.go
+++ b/test/fixedbugs/issue4085a.go
@@ -9,10 +9,10 @@ package main
 type T []int
 
 func main() {
-\t_ = make(T, -1)       // ERROR "negative"
-\t_ = make(T, 0.5)       // ERROR "constant 0.5 truncated to integer"
-\t_ = make(T, 1.0)       // ok
-\t_ = make(T, 1<<63)  // ERROR "len argument too large"
-\t_ = make(T, 0, -1)    // ERROR "negative cap"
+\t_ = make(T, -1)    // ERROR "negative"
+\t_ = make(T, 0.5)   // ERROR "constant 0.5 truncated to integer|non-integer len argument"
+\t_ = make(T, 1.0)   // ok
+\t_ = make(T, 1<<63) // ERROR "len argument too large"
+\t_ = make(T, 0, -1) // ERROR "negative cap"
 \t_ = make(T, 10, 0) // ERROR "len larger than cap"
 }

コアとなるコードの解説

このコミットは、Go言語のテストファイル test/const6.gotest/fixedbugs/issue4085a.go における // ERROR ディレクティブの正規表現パターンを修正しています。

test/const6.go の変更

このファイルでは、定数式の型チェックに関するコンパイルエラーをテストしています。 変更前は、c1 == c2c1 && c2 のような型不一致の操作に対して、ERROR "mismatched types" という単一のエラーメッセージを期待していました。 変更後には、ERROR "mismatched types|incompatible types" となっています。これは、Goの公式コンパイラ gc が "mismatched types" を出力するのに対し、gccgo が "incompatible types" を出力する可能性があるため、両方のメッセージを許容するようにパターンを拡張しています。これにより、どちらのコンパイラでテストを実行しても、型不一致のエラーが正しく検出されるようになります。

test/fixedbugs/issue4085a.go の変更

このファイルは、make 関数の不正な引数に関するバグ修正のテストケースを含んでいます。 特に注目すべきは、_ = make(T, 0.5) の行です。 変更前は、ERROR "constant 0.5 truncated to integer" というエラーメッセージを期待していました。これは、makelen 引数に浮動小数点数が渡された場合に、コンパイラがその定数を整数に切り捨てようとすることを示すエラーです。 変更後には、ERROR "constant 0.5 truncated to integer|non-integer len argument" となっています。これは、gc が "constant 0.5 truncated to integer" を出力するのに対し、gccgo が "non-integer len argument" のような、より一般的な「非整数型のlen引数」というメッセージを出力する可能性があるためです。この変更により、make 関数の引数チェックに関するテストが gccgo でも正しく機能するようになります。

これらの変更は、Go言語のテストスイートが複数のコンパイラ実装(特に gcgccgo)に対して堅牢であり、コンパイラ間のエラーメッセージの差異によってテストが不必要に失敗しないようにするために重要です。

関連リンク

参考にした情報源リンク