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

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

このコミットは、Goコンパイラ (cmd/gc) とGoリンカ (cmd/ld) におけるビルド時の問題を修正するものです。具体的には、未使用変数の削除と、printf(またはそれに類する診断メッセージ出力関数)における変数の誤用を修正しています。

コミット

commit 7666f24a8438937dde212da8cbd9cb2c940a1752
Author: Ian Lance Taylor <iant@golang.org>
Date:   Fri Jul 19 15:04:53 2013 -0700

    cmd/gc, cmd/ld: fix build: remove unused var, use correct var in printf
    
    Fixes #5924.
    
    R=golang-dev, khr, rsc
    CC=golang-dev
    https://golang.org/cl/11606043

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

https://github.com/golang/go/commit/7666f24a8438937dde212da8cbd9cb2c940a1752

元コミット内容

cmd/gc, cmd/ld: fix build: remove unused var, use correct var in printf

このコミットメッセージは、Goコンパイラ (cmd/gc) とGoリンカ (cmd/ld) のビルドプロセスにおける2つの問題を修正したことを示しています。一つは未使用変数の削除、もう一つはprintf形式の出力における変数の誤用です。

変更の背景

このコミットは、GoのIssue #5924を修正するために行われました。ただし、現在のGoのIssueトラッカーではこの番号のIssueは見つかりませんでした。これは、Issue番号が変更されたか、非常に古いIssueであるためアーカイブされたか、あるいは内部的なIssueトラッカーの番号である可能性があります。

コミットメッセージとコードの変更内容から推測すると、ビルドシステムが未使用変数を警告またはエラーとして扱っていたか、あるいは単にコードのクリーンアップの一環として不要な変数が削除されたと考えられます。また、printfの引数間違いは、診断メッセージが正しく表示されない、あるいは誤った情報が表示される原因となっていた可能性があります。これらの問題は、Goのビルドプロセスにおける堅牢性と正確性を向上させるために修正されました。

前提知識の解説

このコミットを理解するためには、以下のGoの内部構造とツールに関する知識が必要です。

  • Goコンパイラ (cmd/gc): Go言語のソースコードを機械語に変換する主要なコンパイラです。Goのコンパイラは、C言語で書かれており、独自のAST (Abstract Syntax Tree) 表現や中間表現を使用しています。pgen.cは、Goのプログラムをコンパイルする過程で、プロローグやエピローグの生成、関数データの処理などを行う部分に関連している可能性があります。
  • Goリンカ (cmd/ld): コンパイラによって生成されたオブジェクトファイルやライブラリを結合し、実行可能なバイナリを生成するツールです。リンカは、シンボルの解決、セクションの配置、リロケーションの適用など、最終的な実行ファイルを構築するための重要な役割を担います。lib.cは、リンカのライブラリ処理や、特定のセクション(例えば、Goのランタイムが使用するメタデータ)の生成に関連するコードが含まれている可能性があります。
  • Prog構造体: Goのコンパイラやリンカの内部で、機械語命令や擬似命令を表すために使用される構造体です。これは、アセンブリコードの命令に対応する抽象的な表現であり、コンパイラが生成し、リンカが処理します。
  • AFUNCDATA: Goのランタイムが使用する関数関連のメタデータを表す擬似命令(または命令タイプ)です。Goのガベージコレクタやプロファイラは、このAFUNCDATAによって記述された情報(例えば、関数のスタックフレームのレイアウトや、ヒープ上のポインタの位置など)を利用して動作します。
  • APCDATA: Goのランタイムが使用するPC (Program Counter) 関連のメタデータを表す擬似命令です。これは、特定のPC値(命令アドレス)に関連付けられた情報(例えば、スタックトレースの生成に必要な情報や、ガベージコレクタが使用する情報)を提供します。
  • diag関数: Goのコンパイラやリンカの内部で使用される診断メッセージ出力関数です。これは、コンパイル時やリンク時に発生したエラーや警告をユーザーに報告するために使用されます。C言語のprintfに似た形式指定子を使用することが一般的です。

技術的詳細

このコミットは、Goのコンパイラとリンカの内部コードにおける2つの異なる問題を修正しています。

  1. src/cmd/gc/pgen.c における未使用変数の削除:

    • 元のコードでは、compile関数内でProg *pfuncdataという変数が宣言されていましたが、その後のコードでこの変数が使用されていませんでした。
    • Goのビルドシステムや静的解析ツールは、未使用変数を警告またはエラーとして検出することがあります。これは、コードの品質を保ち、潜在的なバグを防ぐための良いプラクティスです。
    • 修正では、pfuncdata変数の宣言が削除され、gins(AFUNCDATA, &nod1, gcnod);の呼び出し結果が直接使用されるようになりました。これにより、コードがより簡潔になり、未使用変数に関する警告が解消されます。
  2. src/cmd/ld/lib.c におけるprintf引数の修正:

    • pclntab関数内で、AFUNCDATA命令の多重定義を検出する診断メッセージが出力される箇所がありました。
    • 元のコードでは、diag("multiple definitions for FUNCDATA $%d", i); となっていましたが、iという変数はこのコンテキストでは適切ではありませんでした。
    • AFUNCDATA命令は、p->from.offsetというフィールドに特定のオフセット値を持っており、このオフセット値がFUNCDATAの識別子として機能します。
    • 修正では、diag("multiple definitions for FUNCDATA $%d", p->from.offset); となり、診断メッセージがAFUNCDATAの実際のオフセット値(識別子)を表示するように変更されました。これにより、リンカが報告するエラーメッセージがより正確で、デバッグに役立つ情報を提供するようになります。

これらの修正は、Goのコンパイラとリンカの内部的な健全性を保ち、ビルドプロセスをより堅牢にするためのものです。

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

src/cmd/gc/pgen.c

--- a/src/cmd/gc/pgen.c
+++ b/src/cmd/gc/pgen.c
@@ -17,7 +17,7 @@ compile(Node *fn)
 {
 	Plist *pl;
 	Node nod1, *n, *gcnod;
-	Prog *pfuncdata, *ptxt, *p, *p1;
+	Prog *ptxt, *p, *p1;
 	int32 lno;
 	Type *t;
 	Iter save;
@@ -99,7 +99,7 @@ compile(Node *fn)
 	gcnod->class = PEXTERN;
 
 	nodconst(&nod1, types[TINT32], FUNCDATA_GC);
-	pfuncdata = gins(AFUNCDATA, &nod1, gcnod);
+	gins(AFUNCDATA, &nod1, gcnod);
 
 	for(t=curfn->paramfld; t; t=t->down)
 		gtrack(tracksym(t->type));

src/cmd/ld/lib.c

--- a/src/cmd/ld/lib.c
+++ b/src/cmd/ld/lib.c
@@ -2458,7 +2458,7 @@ pclntab(void)
 		for(p = cursym->text; p != P; p = p->link) {
 			if(p->as == AFUNCDATA) {
 				if((havefunc[p->from.offset/32]>>(p->from.offset%32))&1)
-					diag("multiple definitions for FUNCDATA $%d", i);
+					diag("multiple definitions for FUNCDATA $%d", p->from.offset);
 				havefunc[p->from.offset/32] |= 1<<(p->from.offset%32);
 			}
 			if(p->as == APCDATA)

コアとなるコードの解説

src/cmd/gc/pgen.c の変更

  • Prog *pfuncdata, *ptxt, *p, *p1; から Prog *ptxt, *p, *p1; への変更:
    • pfuncdata変数の宣言が削除されました。これは、この変数が宣言されても、その値が後続のコードで利用されていなかったためです。
    • pfuncdata = gins(AFUNCDATA, &nod1, gcnod); の行が gins(AFUNCDATA, &nod1, gcnod); に変更されました。gins関数はProgポインタを返す関数ですが、その戻り値がpfuncdataに代入される必要がなくなったため、直接呼び出す形になりました。
    • この変更は、コードの冗長性を排除し、コンパイラの内部コードをよりクリーンに保つためのものです。

src/cmd/ld/lib.c の変更

  • diag("multiple definitions for FUNCDATA $%d", i); から diag("multiple definitions for FUNCDATA $%d", p->from.offset); への変更:
    • この変更は、リンカがAFUNCDATA命令の多重定義を検出した際に表示する診断メッセージの正確性を向上させるものです。
    • AFUNCDATA命令は、Goのランタイムが使用する関数関連のメタデータを表します。p->from.offsetは、このAFUNCDATAが参照する特定のデータ(例えば、ガベージコレクション情報)のオフセットを示しています。
    • 元のコードでは、ループ変数iが誤って使用されていましたが、これはAFUNCDATAの実際の識別子とは関係ありませんでした。
    • 修正後、p->from.offsetが使用されることで、どのFUNCDATAが多重定義されているのかがメッセージから明確にわかるようになり、デバッグが容易になります。これは、リンカが生成するエラーメッセージの品質を向上させる重要な修正です。

関連リンク

参考にした情報源リンク

  • Go言語のソースコード (特にsrc/cmd/gcsrc/cmd/ldディレクトリ)
  • Go言語のコンパイラとリンカに関するドキュメントやブログ記事 (一般的なGoの内部構造に関する情報)
  • GoのIssueトラッカー (過去のIssueの検索)
  • Gerrit (Goのコードレビューシステム)
  • C言語のprintf関数の動作に関する一般的な知識
  • コンパイラとリンカの基本的な概念に関する知識