[インデックス 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つの異なる問題を修正しています。
-
src/cmd/gc/pgen.c
における未使用変数の削除:- 元のコードでは、
compile
関数内でProg *pfuncdata
という変数が宣言されていましたが、その後のコードでこの変数が使用されていませんでした。 - Goのビルドシステムや静的解析ツールは、未使用変数を警告またはエラーとして検出することがあります。これは、コードの品質を保ち、潜在的なバグを防ぐための良いプラクティスです。
- 修正では、
pfuncdata
変数の宣言が削除され、gins(AFUNCDATA, &nod1, gcnod);
の呼び出し結果が直接使用されるようになりました。これにより、コードがより簡潔になり、未使用変数に関する警告が解消されます。
- 元のコードでは、
-
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言語の公式リポジトリ: https://github.com/golang/go
- GoのIssueトラッカー: https://github.com/golang/go/issues (ただし、Issue #5924は現在見つかりません)
- Goのコードレビューシステム (Gerrit): https://go-review.googlesource.com/ (コミットメッセージにある
https://golang.org/cl/11606043
は、このGerritの変更リストへのリンクです)
参考にした情報源リンク
- Go言語のソースコード (特に
src/cmd/gc
とsrc/cmd/ld
ディレクトリ) - Go言語のコンパイラとリンカに関するドキュメントやブログ記事 (一般的なGoの内部構造に関する情報)
- GoのIssueトラッカー (過去のIssueの検索)
- Gerrit (Goのコードレビューシステム)
- C言語の
printf
関数の動作に関する一般的な知識 - コンパイラとリンカの基本的な概念に関する知識