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

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

このコミットは、Goコンパイラ(gc)におけるエラー報告の改善を目的としています。特に、コンパイル時に発生しうる「誤ったコンパイル(miscompiling)」を防ぐため、サイズに関する制約を超過するような状況に対して、より分かりやすいエラーメッセージを出力するように変更が加えられています。これにより、開発者は問題の原因を早期に特定し、修正できるようになります。

コミット

commit a6c49098bcddd3af21640b512257289c47f5e724
Author: Luuk van Dijk <lvd@golang.org>
Date:   Tue Jan 10 11:19:22 2012 +0100

    gc: Nicer errors before miscompiling.
    
    This fixes issue 2444.
    
    A big cleanup of all 31/32bit size boundaries i'll leave for another cl though.  (see also issue 1700).
    
    R=rsc
    CC=golang-dev
    https://golang.org/cl/5484058

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

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

元コミット内容

このコミットの元のメッセージは以下の通りです。

gc: Nicer errors before miscompiling.

This fixes issue 2444.

A big cleanup of all 31/32bit size boundaries i'll leave for another cl though.  (see also issue 1700).

このメッセージは、Goコンパイラ(gc)が誤ったコンパイルを行う前に、より適切なエラーメッセージを生成するように改善されたことを示しています。具体的には、GoのIssue 2444を修正するものであり、31ビット/32ビットのサイズ境界に関する大規模なクリーンアップは、Issue 1700に関連して、将来の別の変更リスト(CL: Change List)に委ねられることが言及されています。

変更の背景

Goコンパイラは、プログラムを機械語に変換する際に、メモリ割り当てやデータ構造のサイズ計算を行います。特に、32ビットシステムのようなアドレス空間が限られている環境では、データ型やスタックフレームのサイズがシステムが扱える最大値を超えると、コンパイラが誤ったコードを生成したり、実行時に予期せぬ動作(クラッシュなど)を引き起こしたりする可能性があります。

このコミットが修正するIssue 2444は、まさにこのような状況、つまりコンパイラが誤ったコードを生成する前に、開発者に明確なエラーを通知できていなかった問題に対処しています。以前のバージョンでは、サイズが大きすぎる配列やスタックフレームが定義された場合、コンパイラは警告なしにコンパイルを続行し、結果として実行時に問題が発生する可能性がありました。

この変更の背景には、コンパイラの堅牢性を高め、開発者がより安全にコードを記述できるようにするというGo言語開発チームの意図があります。特に、異なるアーキテクチャ(32ビットと64ビット)間での互換性と予測可能性を向上させるために、サイズに関する制約を明示的にチェックし、エラーとして報告することが重要視されました。

前提知識の解説

このコミットを理解するためには、以下の概念が役立ちます。

  • Goコンパイラ (gc): Go言語の公式コンパイラです。5g (ARM), 6g (x86-64), 8g (x86) は、それぞれ異なるCPUアーキテクチャ向けのGoコンパイラのフロントエンドを指します。これらはGoのソースコードを中間表現に変換し、最終的に機械語を生成します。
  • int32int64: これらはGo言語(およびC言語など)における整数型です。int32 は32ビット(約20億)までの整数値を表現でき、int64 は64ビット(約900京)までの整数値を表現できます。32ビットシステムでは、ポインタやサイズを表すデフォルトの整数型が32ビットに制限されることが多く、これが大きなデータ構造を扱う際の制約となります。
  • スタックフレーム (Stack Frame): 関数が呼び出されるたびに、その関数のローカル変数、引数、戻りアドレスなどを格納するために、プログラムのスタックメモリ上に確保される領域です。スタックフレームのサイズがシステムの上限を超えると、スタックオーバーフローなどの問題が発生します。
  • 誤ったコンパイル (Miscompiling): コンパイラがソースコードを正しく解釈せず、意図しない動作をする機械語を生成してしまうことです。これは、コンパイラのバグ、またはコンパイラが想定していない極端な入力(例:非常に大きなデータ構造)によって発生することがあります。
  • fatalyyerror:
    • fatal: コンパイラが回復不能なエラーを検出した際に使用される関数で、通常はコンパイルプロセスを即座に終了させます。
    • yyerror: より一般的なエラー報告メカニズムで、エラーメッセージを出力した後もコンパイルプロセスを続行し、他のエラーも検出できるようにします。
  • Ullman数 (Ullman Number): コンパイラ最適化の文脈で、式の評価順序を決定するために使用される概念です。UINF は「無限大」を意味し、非常に複雑な式や、評価順序が自明でない場合に用いられることがあります。

技術的詳細

このコミットの技術的な変更点は、主に以下の3つの側面から構成されています。

  1. sgen 関数の引数型の変更とサイズチェックの強化:

    • src/cmd/5g/cgen.c, src/cmd/6g/cgen.c, src/cmd/8g/cgen.c 内の sgen 関数(おそらくメモリコピーや構造体割り当てに関連するコード生成を行う関数)の第3引数 w の型が int32 から int64 に変更されました。これは、より大きなサイズを扱うことができるようにするためです。
    • sgen 関数内に、w < 0 || (int32)w != w という新しいチェックが追加されました。これは、w が負の値である場合、または wint32 の範囲を超えている場合に fatal エラーを発生させます。これにより、32ビットシステムで int64 の値が int32 に収まらない場合に、誤ったサイズで処理されることを防ぎます。
    • print デバッグ出力のフォーマット文字列も %d から %lld または %ld に変更され、int64 の値が正しく表示されるようになりました。
    • アラインメントチェックのエラーメッセージも %d から %lld に変更され、より大きなサイズが報告されるようになりました。
  2. 型幅のチェックの追加 (src/cmd/gc/align.c):

    • dowidth 関数内に、if(widthptr == 4 && w != (int32)w) というチェックが追加されました。widthptr == 4 は32ビットシステムであることを示唆しており、w != (int32)w は計算された型幅 w が32ビット整数の範囲を超えていることを意味します。この条件が真の場合、yyerror("type %T too large", t) というエラーメッセージが出力されます。これにより、32ビット環境で型が大きすぎる場合に、コンパイル時にエラーが報告されるようになります。
  3. スタックフレームサイズのチェックの追加 (src/cmd/gc/pgen.c):

    • compile 関数内に、if(stksize+maxarg > (1ULL<<31)) というチェックが追加されました。stksize は現在のスタックサイズ、maxarg は関数呼び出しの引数によって必要となる最大スタックサイズです。(1ULL<<31) は2GB(2の31乗)を表します。このチェックは、スタックフレームの合計サイズが2GBを超える場合に yyerror("stack frame too large (>2GB)") というエラーメッセージを出力します。これは、特に大きな配列をローカル変数として宣言した場合などに発生しうる、スタックオーバーフローのリスクを事前に検出するためのものです。

これらの変更は、コンパイラが潜在的な問題を早期に検出し、開発者に明確なフィードバックを提供することで、デバッグの手間を減らし、より堅牢なGoプログラムの作成を支援します。

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

このコミットにおけるコアとなるコードの変更箇所は、主に以下のファイルと関数に集中しています。

  • src/cmd/5g/cgen.c, src/cmd/6g/cgen.c, src/cmd/8g/cgen.c および対応するヘッダファイル (gg.h):
    • sgen 関数のシグネチャ変更: int32 w から int64 w へ。
    • sgen 関数内での新しいサイズチェック: if(w < 0 || (int32)w != w)
  • src/cmd/gc/align.c:
    • dowidth 関数内での型幅チェックの追加: if(widthptr == 4 && w != (int32)w)
  • src/cmd/gc/pgen.c:
    • compile 関数内でのスタックフレームサイズチェックの追加: if(stksize+maxarg > (1ULL<<31))
  • test/fixedbugs/bug385_32.go および test/fixedbugs/bug385_64.go:
    • 新しいエラーメッセージが正しく出力されることを検証するためのテストケースの追加。

コアとなるコードの解説

sgen 関数の変更 (src/cmd/{5,6,8}g/cgen.c および gg.h)

sgen 関数は、Goコンパイラのバックエンドの一部であり、おそらくメモリブロックのコピーや構造体の割り当てに関連するコードを生成します。この関数は、コピーするデータのサイズを w 引数として受け取ります。

// 変更前 (例: 5g/cgen.c)
void
sgen(Node *n, Node *res, int32 w)
{
    // ...
    if(debug['g']) {
        print("\nsgen w=%d\n", w);
        // ...
    }
    if(w < 0)
        fatal("sgen copy %d", w);
    // ...
    if(w%align)
        fatal("sgen: unaligned size %d (align=%d) for %T", w, align, n->type);
    // ...
}

// 変更後 (例: 5g/cgen.c)
void
sgen(Node *n, Node *res, int64 w) // int32 から int64 へ変更
{
    // ...
    if(debug['g']) {
        print("\nsgen w=%lld\n", w); // フォーマット文字列も変更
        // ...
    }
    // 新しいチェックの追加
    if(w < 0 || (int32)w != w)
        fatal("sgen copy %lld", w); // エラーメッセージも変更
    // ...
    if(w%align)
        fatal("sgen: unaligned size %lld (align=%d) for %T", w, align, n->type); // エラーメッセージも変更
    // ...
}

この変更の意図は、sgen が扱うサイズ wint32 の最大値(約2GB)を超える可能性があるため、int64 に拡張することで、より大きなデータ構造のコピーをサポートすることです。同時に、w < 0 || (int32)w != w というチェックを追加することで、w が負の値である場合や、int64 で表現されている wint32 の範囲に収まらない場合に、コンパイラが誤った処理を行う前に fatal エラーを発生させるようにしました。これにより、特に32ビットシステムで、サイズオーバーフローによる誤ったコンパイルを防ぎます。

dowidth 関数内の型幅チェック (src/cmd/gc/align.c)

dowidth 関数は、Goの型(構造体、配列など)のメモリ上の幅(サイズ)を計算する役割を担っています。

// 変更後
void
dowidth(Type *t)
{
    // ...
    if(widthptr == 4 && w != (int32)w) // 新しいチェックの追加
        yyerror("type %T too large", t);
    // ...
    t->width = w;
    // ...
}

widthptr == 4 は、コンパイラが32ビットアーキテクチャ向けにビルドされていることを示します(ポインタのサイズが4バイト)。この条件下で w != (int32)w が真となる場合、計算された型 t の幅 w が32ビット整数の範囲を超えていることを意味します。このような場合、yyerror を使って「type too large」というエラーを出力し、開発者に型が大きすぎることを通知します。これにより、32ビットシステムでメモリに収まらないような巨大な型が定義された際に、コンパイル時にエラーとして検出できるようになります。

compile 関数内のスタックフレームサイズチェック (src/cmd/gc/pgen.c)

compile 関数は、Goの関数をコンパイルする主要な部分です。この中で、関数のスタックフレームに必要なメモリサイズが計算されます。

// 変更後
void
compile(Node *fn)
{
    // ...
    setlineno(curfn);
    if(stksize+maxarg > (1ULL<<31)) // 新しいチェックの追加
        yyerror("stack frame too large (>2GB)");
    // ...
    defframe(ptxt);
    // ...
}

stksize は関数内のローカル変数などが占めるスタックサイズ、maxarg は関数呼び出し時に引数として渡されるデータが占める最大スタックサイズです。これらを合計した stksize+maxarg(1ULL<<31)(2GB)を超える場合、yyerror を使って「stack frame too large (>2GB)」というエラーを出力します。これは、特に非常に大きな配列をローカル変数として宣言した場合などに、スタックフレームがシステムの上限を超えてしまうことを防ぐための重要なチェックです。これにより、実行時のスタックオーバーフローを防ぎ、より安定したプログラムを保証します。

テストケース (test/fixedbugs/bug385_32.go, test/fixedbugs/bug385_64.go)

これらのテストファイルは、上記の変更によって新しいエラーメッセージが正しく出力されることを検証するために追加されました。

  • bug385_32.go: 32ビット環境で、非常に大きな配列 [1000200030]int を宣言した場合に、「type .* too large」というエラーが出力されることを期待します。
  • bug385_64.go: 64ビット環境で、同じく非常に大きな配列を宣言した場合に、「stack frame too large」というエラーが出力されることを期待します。これは、64ビット環境では型自体は大きすぎないが、スタックフレーム全体としては大きすぎるという状況をテストしています。

これらのテストは、コンパイラが異なるアーキテクチャで適切にサイズ制約をチェックし、開発者に有用なエラーメッセージを提供することを確認します。

関連リンク

参考にした情報源リンク

  • Go言語の公式ドキュメント (コンパイラ、型、メモリ管理に関する一般的な情報)
  • Go言語のソースコード (特に src/cmd/gc ディレクトリ内のファイル)
  • Go言語のIssueトラッカー (Issue 2444, Issue 1700 の詳細)
  • コンパイラ設計に関する一般的な知識 (スタックフレーム、型システム、エラー処理)
  • C言語のデータ型 (int32_t, int64_t など、GoコンパイラのC言語実装の理解に役立つ)```markdown

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

このコミットは、Goコンパイラ(gc)におけるエラー報告の改善を目的としています。特に、コンパイル時に発生しうる「誤ったコンパイル(miscompiling)」を防ぐため、サイズに関する制約を超過するような状況に対して、より分かりやすいエラーメッセージを出力するように変更が加えられています。これにより、開発者は問題の原因を早期に特定し、修正できるようになります。

コミット

commit a6c49098bcddd3af21640b512257289c47f5e724
Author: Luuk van Dijk <lvd@golang.org>
Date:   Tue Jan 10 11:19:22 2012 +0100

    gc: Nicer errors before miscompiling.
    
    This fixes issue 2444.
    
    A big cleanup of all 31/32bit size boundaries i'll leave for another cl though.  (see also issue 1700).
    
    R=rsc
    CC=golang-dev
    https://golang.org/cl/5484058

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

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

元コミット内容

このコミットの元のメッセージは以下の通りです。

gc: Nicer errors before miscompiling.

This fixes issue 2444.

A big cleanup of all 31/32bit size boundaries i'll leave for another cl though.  (see also issue 1700).

このメッセージは、Goコンパイラ(gc)が誤ったコンパイルを行う前に、より適切なエラーメッセージを生成するように改善されたことを示しています。具体的には、GoのIssue 2444を修正するものであり、31ビット/32ビットのサイズ境界に関する大規模なクリーンアップは、Issue 1700に関連して、将来の別の変更リスト(CL: Change List)に委ねられることが言及されています。

変更の背景

Goコンパイラは、プログラムを機械語に変換する際に、メモリ割り当てやデータ構造のサイズ計算を行います。特に、32ビットシステムのようなアドレス空間が限られている環境では、データ型やスタックフレームのサイズがシステムが扱える最大値を超えると、コンパイラが誤ったコードを生成したり、実行時に予期せぬ動作(クラッシュなど)を引き起こしたりする可能性があります。

このコミットが修正するIssue 2444は、まさにこのような状況、つまりコンパイラが誤ったコードを生成する前に、開発者に明確なエラーを通知できていなかった問題に対処しています。以前のバージョンでは、サイズが大きすぎる配列やスタックフレームが定義された場合、コンパイラは警告なしにコンパイルを続行し、結果として実行時に問題が発生する可能性がありました。

この変更の背景には、コンパイラの堅牢性を高め、開発者がより安全にコードを記述できるようにするというGo言語開発チームの意図があります。特に、異なるアーキテクチャ(32ビットと64ビット)間での互換性と予測可能性を向上させるために、サイズに関する制約を明示的にチェックし、エラーとして報告することが重要視されました。

前提知識の解説

このコミットを理解するためには、以下の概念が役立ちます。

  • Goコンパイラ (gc): Go言語の公式コンパイラです。5g (ARM), 6g (x86-64), 8g (x86) は、それぞれ異なるCPUアーキテクチャ向けのGoコンパイラのフロントエンドを指します。これらはGoのソースコードを中間表現に変換し、最終的に機械語を生成します。
  • int32int64: これらはGo言語(およびC言語など)における整数型です。int32 は32ビット(約20億)までの整数値を表現でき、int64 は64ビット(約900京)までの整数値を表現できます。32ビットシステムでは、ポインタやサイズを表すデフォルトの整数型が32ビットに制限されることが多く、これが大きなデータ構造を扱う際の制約となります。
  • スタックフレーム (Stack Frame): 関数が呼び出されるたびに、その関数のローカル変数、引数、戻りアドレスなどを格納するために、プログラムのスタックメモリ上に確保される領域です。スタックフレームのサイズがシステムの上限を超えると、スタックオーバーフローなどの問題が発生します。
  • 誤ったコンパイル (Miscompiling): コンパイラがソースコードを正しく解釈せず、意図しない動作をする機械語を生成してしまうことです。これは、コンパイラのバグ、またはコンパイラが想定していない極端な入力(例:非常に大きなデータ構造)によって発生することがあります。
  • fatalyyerror:
    • fatal: コンパイラが回復不能なエラーを検出した際に使用される関数で、通常はコンパイルプロセスを即座に終了させます。
    • yyerror: より一般的なエラー報告メカニズムで、エラーメッセージを出力した後もコンパイルプロセスを続行し、他のエラーも検出できるようにします。
  • Ullman数 (Ullman Number): コンパイラ最適化の文脈で、式の評価順序を決定するために使用される概念です。UINF は「無限大」を意味し、非常に複雑な式や、評価順序が自明でない場合に用いられることがあります。

技術的詳細

このコミットの技術的な変更点は、主に以下の3つの側面から構成されています。

  1. sgen 関数の引数型の変更とサイズチェックの強化:

    • src/cmd/5g/cgen.c, src/cmd/6g/cgen.c, src/cmd/8g/cgen.c 内の sgen 関数(おそらくメモリコピーや構造体割り当てに関連するコード生成を行う関数)の第3引数 w の型が int32 から int64 に変更されました。これは、より大きなサイズを扱うことができるようにするためです。
    • sgen 関数内に、w < 0 || (int32)w != w という新しいチェックが追加されました。これは、w が負の値である場合、または wint32 の範囲を超えている場合に fatal エラーを発生させます。これにより、32ビットシステムで int64 の値が int32 に収まらない場合に、誤ったサイズで処理されることを防ぎます。
    • print デバッグ出力のフォーマット文字列も %d から %lld または %ld に変更され、int64 の値が正しく表示されるようになりました。
    • アラインメントチェックのエラーメッセージも %d から %lld に変更され、より大きなサイズが報告されるようになりました。
  2. 型幅のチェックの追加 (src/cmd/gc/align.c):

    • dowidth 関数内に、if(widthptr == 4 && w != (int32)w) というチェックが追加されました。widthptr == 4 は32ビットシステムであることを示唆しており、w != (int32)w は計算された型幅 w が32ビット整数の範囲を超えていることを意味します。この条件が真の場合、yyerror("type %T too large", t) というエラーメッセージが出力されます。これにより、32ビット環境で型が大きすぎる場合に、コンパイル時にエラーが報告されるようになります。
  3. スタックフレームサイズのチェックの追加 (src/cmd/gc/pgen.c):

    • compile 関数内に、if(stksize+maxarg > (1ULL<<31)) というチェックが追加されました。stksize は現在のスタックサイズ、maxarg は関数呼び出しの引数によって必要となる最大スタックサイズです。(1ULL<<31) は2GB(2の31乗)を表します。このチェックは、スタックフレームの合計サイズが2GBを超える場合に yyerror("stack frame too large (>2GB)") というエラーメッセージを出力します。これは、特に大きな配列をローカル変数として宣言した場合などに発生しうる、スタックオーバーフローのリスクを事前に検出するためのものです。

これらの変更は、コンパイラが潜在的な問題を早期に検出し、開発者に明確なフィードバックを提供することで、デバッグの手間を減らし、より堅牢なGoプログラムの作成を支援します。

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

このコミットにおけるコアとなるコードの変更箇所は、主に以下のファイルと関数に集中しています。

  • src/cmd/5g/cgen.c, src/cmd/6g/cgen.c, src/cmd/8g/cgen.c および対応するヘッダファイル (gg.h):
    • sgen 関数のシグネチャ変更: int32 w から int64 w へ。
    • sgen 関数内での新しいサイズチェック: if(w < 0 || (int32)w != w)
  • src/cmd/gc/align.c:
    • dowidth 関数内での型幅チェックの追加: if(widthptr == 4 && w != (int32)w)
  • src/cmd/gc/pgen.c:
    • compile 関数内でのスタックフレームサイズチェックの追加: if(stksize+maxarg > (1ULL<<31))
  • test/fixedbugs/bug385_32.go および test/fixedbugs/bug385_64.go:
    • 新しいエラーメッセージが正しく出力されることを検証するためのテストケースの追加。

コアとなるコードの解説

sgen 関数の変更 (src/cmd/{5,6,8}g/cgen.c および gg.h)

sgen 関数は、Goコンパイラのバックエンドの一部であり、おそらくメモリブロックのコピーや構造体の割り当てに関連するコードを生成します。この関数は、コピーするデータのサイズを w 引数として受け取ります。

// 変更前 (例: 5g/cgen.c)
void
sgen(Node *n, Node *res, int32 w)
{
    // ...
    if(debug['g']) {
        print("\nsgen w=%d\n", w);
        // ...
    }
    if(w < 0)
        fatal("sgen copy %d", w);
    // ...
    if(w%align)
        fatal("sgen: unaligned size %d (align=%d) for %T", w, align, n->type);
    // ...
}

// 変更後 (例: 5g/cgen.c)
void
sgen(Node *n, Node *res, int64 w) // int32 から int64 へ変更
{
    // ...
    if(debug['g']) {
        print("\nsgen w=%lld\n", w); // フォーマット文字列も変更
        // ...
    }
    // 新しいチェックの追加
    if(w < 0 || (int32)w != w)
        fatal("sgen copy %lld", w); // エラーメッセージも変更
    // ...
    if(w%align)
        fatal("sgen: unaligned size %lld (align=%d) for %T", w, align, n->type); // エラーメッセージも変更
    // ...
}

この変更の意図は、sgen が扱うサイズ wint32 の最大値(約2GB)を超える可能性があるため、int64 に拡張することで、より大きなデータ構造のコピーをサポートすることです。同時に、w < 0 || (int32)w != w というチェックを追加することで、w が負の値である場合や、int64 で表現されている wint32 の範囲に収まらない場合に、コンパイラが誤った処理を行う前に fatal エラーを発生させるようにしました。これにより、特に32ビットシステムで、サイズオーバーフローによる誤ったコンパイルを防ぎます。

dowidth 関数内の型幅チェック (src/cmd/gc/align.c)

dowidth 関数は、Goの型(構造体、配列など)のメモリ上の幅(サイズ)を計算する役割を担っています。

// 変更後
void
dowidth(Type *t)
{
    // ...
    if(widthptr == 4 && w != (int32)w) // 新しいチェックの追加
        yyerror("type %T too large", t);
    // ...
    t->width = w;
    // ...
}

widthptr == 4 は、コンパイラが32ビットアーキテクチャ向けにビルドされていることを示します(ポインタのサイズが4バイト)。この条件下で w != (int32)w が真となる場合、計算された型 t の幅 w が32ビット整数の範囲を超えていることを意味します。このような場合、yyerror を使って「type too large」というエラーを出力し、開発者に型が大きすぎることを通知します。これにより、32ビットシステムでメモリに収まらないような巨大な型が定義された際に、コンパイル時にエラーとして検出できるようになります。

compile 関数内のスタックフレームサイズチェック (src/cmd/gc/pgen.c)

compile 関数は、Goの関数をコンパイルする主要な部分です。この中で、関数のスタックフレームに必要なメモリサイズが計算されます。

// 変更後
void
compile(Node *fn)
{
    // ...
    setlineno(curfn);
    if(stksize+maxarg > (1ULL<<31)) // 新しいチェックの追加
        yyerror("stack frame too large (>2GB)");
    // ...
    defframe(ptxt);
    // ...
}

stksize は関数内のローカル変数などが占めるスタックサイズ、maxarg は関数呼び出し時に引数として渡されるデータが占める最大スタックサイズです。これらを合計した stksize+maxarg(1ULL<<31)(2GB)を超える場合、yyerror を使って「stack frame too large (>2GB)」というエラーを出力します。これは、特に非常に大きな配列をローカル変数として宣言した場合などに、スタックフレームがシステムの上限を超えてしまうことを防ぐための重要なチェックです。これにより、実行時のスタックオーバーフローを防ぎ、より安定したプログラムを保証します。

テストケース (test/fixedbugs/bug385_32.go, test/fixedbugs/bug385_64.go)

これらのテストファイルは、上記の変更によって新しいエラーメッセージが正しく出力されることを検証するために追加されました。

  • bug385_32.go: 32ビット環境で、非常に大きな配列 [1000200030]int を宣言した場合に、「type .* too large」というエラーが出力されることを期待します。
  • bug385_64.go: 64ビット環境で、同じく非常に大きな配列を宣言した場合に、「stack frame too large」というエラーが出力されることを期待します。これは、64ビット環境では型自体は大きすぎないが、スタックフレーム全体としては大きすぎるという状況をテストしています。

これらのテストは、コンパイラが異なるアーキテクチャで適切にサイズ制約をチェックし、開発者に有用なエラーメッセージを提供することを確認します。

関連リンク

参考にした情報源リンク

  • Go言語の公式ドキュメント (コンパイラ、型、メモリ管理に関する一般的な情報)
  • Go言語のソースコード (特に src/cmd/gc ディレクトリ内のファイル)
  • Go言語のIssueトラッカー (Issue 2444, Issue 1700 の詳細)
  • コンパイラ設計に関する一般的な知識 (スタックフレーム、型システム、エラー処理)
  • C言語のデータ型 (int32_t, int64_t など、GoコンパイラのC言語実装の理解に役立つ)