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

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

このコミットは、Go言語のコンパイラ(cmd/gc)とリンカ(cmd/ld)において、Plan 9オペレーティングシステム上で発生していたコンパイラ警告を修正することを目的としています。具体的には、未使用の変数やパラメータの削除、およびprintf形式の関数における型ミスマッチの修正が含まれます。

コミット

commit c2e06e0188a19d66d3a773354ec284e308a03d47
Author: David du Colombier <0intro@gmail.com>
Date:   Sat Mar 30 09:44:52 2013 -0700

    cmd/gc, cmd/ld: fix warnings on Plan 9
    
    src/cmd/gc/closure.c:133 param declared and not used: nowrap
    src/cmd/gc/const.c:1139 set and not used: t1
    src/cmd/ld/data.c:652 format mismatch #llx INT, arg 7
    src/cmd/ld/data.c:652 format mismatch #llx INT, arg 8
    src/cmd/ld/data.c:1230 set and not used: datsize
    
    R=dave, golang-dev, lucio.dere, remyoudompheng, bradfitz
    CC=golang-dev
    https://golang.org/cl/8182043

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

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

元コミット内容

このコミットは、Goコンパイラ(cmd/gc)とGoリンカ(cmd/ld)のソースコードにおける、Plan 9環境でのコンパイラ警告を修正します。具体的には以下の警告が対象です。

  • src/cmd/gc/closure.c:133: nowrapパラメータが宣言されているが使用されていない。
  • src/cmd/gc/const.c:1139: t1変数が設定されているが使用されていない。
  • src/cmd/ld/data.c:652: printf形式のフォーマット指定子%#llxと引数の型がミスマッチしている(引数7と8)。
  • src/cmd/ld/data.c:1230: datsize変数が設定されているが使用されていない。

これらの警告を解消するために、不要なパラメータや変数の削除、および型キャストの追加が行われています。

変更の背景

ソフトウェア開発において、コンパイラ警告は潜在的なバグや非効率なコード、あるいは将来的な互換性の問題を示唆する重要な手がかりとなります。特に、異なるプラットフォーム(この場合はPlan 9)でビルドする際に発生する警告は、そのプラットフォーム固有のコンパイラの挙動や、標準Cライブラリの実装の違いに起因することがよくあります。

このコミットの背景には、Go言語のクロスプラットフォーム対応の一環として、Plan 9環境でのビルドプロセスをクリーンに保ち、警告を排除するという目的があります。警告がない状態は、コードの品質を向上させ、開発者が本当に重要なエラーメッセージに集中できるようにするために不可欠です。また、未使用の変数やパラメータは、コードの可読性を低下させ、誤解を招く可能性があるため、これらを削除することはコードベースの健全性を保つ上で重要です。printfのフォーマットミスマッチは、未定義の動作を引き起こす可能性があり、特に異なるアーキテクチャやコンパイラでは予期せぬ結果を招くため、厳密な型の一致が求められます。

前提知識の解説

このコミットを理解するためには、以下の技術的知識が役立ちます。

  1. Go言語のツールチェイン:
    • cmd/gc: Go言語のコンパイラです。Goのソースコードを機械語に変換する役割を担います。C言語で実装されており、Goのランタイムや標準ライブラリの一部もCで書かれています。
    • cmd/ld: Go言語のリンカです。コンパイラによって生成されたオブジェクトファイルやライブラリを結合し、実行可能なバイナリを生成します。リンカもC言語で実装されています。
  2. Plan 9: ベル研究所で開発された分散オペレーティングシステムです。Unixの思想をさらに推し進めた設計が特徴で、ファイルシステムを中心としたリソース管理や、UTF-8の早期採用などで知られています。Go言語の開発者の一部はPlan 9の設計思想に影響を受けており、Go言語自体もPlan 9のツールチェイン(8c, 8lなど)から派生したコンパイラ・リンカを使用しています。Plan 9のCコンパイラは、標準Cとは異なる独自の拡張や挙動を持つことがあり、特にprintfのフォーマット指定子や整数型の扱いにおいて差異が生じることがあります。
  3. C言語のコンパイラ警告:
    • 「param declared and not used」: 関数パラメータが宣言されているが、関数本体内で一度も使用されていない場合に発生する警告です。これは通常、コードの冗長性や、意図しない設計ミスを示唆します。
    • 「set and not used」: 変数が値を代入されているが、その値が後続のコードで一度も読み出されていない場合に発生する警告です。これも同様に、冗長なコードや論理的な誤りを示唆します。
    • 「format mismatch」: printfsprintfなどのフォーマット文字列関数において、フォーマット指定子(例: %d, %s, %llx)と、それに対応する引数の型が一致しない場合に発生する警告です。これは非常に危険な警告であり、未定義の動作(メモリ破壊、クラッシュ、誤った出力など)を引き起こす可能性があります。特に%llxは通常、long long型の16進数出力を期待しますが、異なるサイズの整数型が渡されると問題が生じます。Plan 9のCコンパイラでは、vlongという型が64ビット整数を表すために使われることがあり、printf%llxを使用する際には、引数を明示的にvlongにキャストする必要がある場合があります。
  4. 型キャスト: C言語において、あるデータ型を別のデータ型に明示的に変換する操作です。printfのフォーマットミスマッチ警告を解消するために、引数の型をフォーマット指定子が期待する型に合わせるために使用されます。

技術的詳細

このコミットで行われた修正は、主に以下の3つのカテゴリに分類されます。

  1. 未使用パラメータの削除 (src/cmd/gc/closure.c):

    • makeclosure関数は、Goのクロージャ(関数がその定義された環境の変数を「捕捉」する機能)を生成する際に使用される内部関数です。
    • 元のコードでは、makeclosure関数はnowrapというint型のパラメータを持っていましたが、このパラメータは関数本体内で一切使用されていませんでした。
    • この修正では、makeclosure関数の宣言と、その呼び出し箇所からnowrapパラメータが完全に削除されました。これにより、コンパイラが「param declared and not used」という警告を発しなくなります。これはコードのクリーンアップと保守性の向上に寄与します。
  2. 未使用変数代入の削除 (src/cmd/gc/const.c):

    • defaultlit関数は、Goのコンパイラがリテラル値の型推論を行う際に関連する処理の一部です。
    • 元のコードでは、t1 = T;という行がありましたが、t1という変数はこの代入の後、どこでも使用されていませんでした。
    • この修正では、この冗長な代入文が削除されました。これにより、コンパイラが「set and not used」という警告を発しなくなります。これもコードの無駄をなくし、コンパイル時の警告を減らすためのクリーンアップです。
  3. printfフォーマットミスマッチの修正 (src/cmd/ld/data.c):

    • datblk関数は、Goのリンカがデータセクションを処理する際、特にリロケーション情報(プログラム実行時にアドレスを修正する必要がある箇所)を出力する部分に関連しています。
    • 問題の行は、デバッグ目的でリロケーション情報をBprint(Plan 9のprint関数に似たもの)で出力する箇所でした。
    • %#llxというフォーマット指定子は、通常64ビットの符号なし整数を16進数で出力することを期待します。しかし、引数として渡されていたr->addr->sym->value+r->addは、Plan 9のCコンパイラ環境では、int型やlong型など、long long(またはPlan 9のvlong)よりも小さいサイズの整数型として扱われていた可能性があります。
    • この型ミスマッチにより、コンパイラは警告を発していました。修正では、これらの引数を明示的に(vlong)にキャストすることで、Bprint関数が期待する型と一致させ、警告を解消しています。vlongはPlan 9のC言語における64ビット整数型であり、これにより正しい値がフォーマットされて出力されるようになります。
    • また、datsize = 0;という未使用の変数代入もこのファイルから削除されています。

これらの修正は、GoのツールチェインがPlan 9を含む多様なプラットフォームでクリーンにビルドされ、安定して動作することを保証するために重要です。警告の排除は、潜在的なバグの発見を容易にし、開発者がより重要な問題に集中できる環境を提供します。

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

src/cmd/gc/closure.c

--- a/src/cmd/gc/closure.c
+++ b/src/cmd/gc/closure.c
@@ -76,7 +76,7 @@ closurebody(NodeList *body)
 	return func;
 }
 
-static Node* makeclosure(Node *func, int nowrap);
+static Node* makeclosure(Node *func);
 
 void
 typecheckclosure(Node *func, int top)
@@ -125,11 +125,11 @@ typecheckclosure(Node *func, int top)
 	}
 
 	// Create top-level function 
-	xtop = list(xtop, makeclosure(func, func->cvars==nil || (top&Ecall)));
+	xtop = list(xtop, makeclosure(func));
 }
 
 static Node*
-makeclosure(Node *func, int nowrap)
+makeclosure(Node *func)
 {
 	Node *xtype, *v, *addr, *xfunc, *cv;
 	NodeList *l, *body;

src/cmd/gc/const.c

--- a/src/cmd/gc/const.c
+++ b/src/cmd/gc/const.c
@@ -1136,7 +1136,6 @@ defaultlit(Node **np, Type *t)
 
 	lno = setlineno(n);
 	ctype = idealkind(n);
-	t1 = T;
 	switch(ctype) {
 	default:
 		if(t != T) {

src/cmd/ld/data.c

--- a/src/cmd/ld/data.c
+++ b/src/cmd/ld/data.c
@@ -650,7 +650,7 @@ datblk(int32 addr, int32 size)
 					break;
 				}
 				Bprint(&bso, "\treloc %.8ux/%d %s %s+%#llx [%#llx]\n",
-					(uint)(sym->value+r->off), r->siz, typ, rsname, r->add, r->sym->value+r->add);
+					(uint)(sym->value+r->off), r->siz, typ, rsname, (vlong)r->add, (vlong)(r->sym->value+r->add));
 			}
 		}				
 	}
@@ -1227,7 +1227,6 @@ dodata(void)
 
 	/* we finished segdata, begin segtext */
 	s = datap;
-	datsize = 0;
 
 	/* read-only data */
 	sect = addsection(&segtext, ".rodata", 04);

コアとなるコードの解説

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

  • 変更前: static Node* makeclosure(Node *func, int nowrap);
  • 変更後: static Node* makeclosure(Node *func);
    • makeclosure関数のプロトタイプ宣言から、未使用のnowrapパラメータが削除されました。
  • 変更前: xtop = list(xtop, makeclosure(func, func->cvars==nil || (top&Ecall)));
  • 変更後: xtop = list(xtop, makeclosure(func));
    • makeclosure関数の呼び出し箇所から、nowrap引数が削除されました。
  • 変更前: static Node* makeclosure(Node *func, int nowrap)
  • 変更後: static Node* makeclosure(Node *func)
    • makeclosure関数の定義から、未使用のnowrapパラメータが削除されました。

これらの変更により、nowrapパラメータが完全にコードベースから取り除かれ、コンパイラが「param declared and not used」という警告を発しなくなりました。

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

  • 変更前: t1 = T;
  • 変更後: (行削除)
    • defaultlit関数内で、t1という変数にTという値が代入されていましたが、このt1はその後一切使用されていませんでした。この行を削除することで、「set and not used」という警告が解消されました。

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

  • 変更前: Bprint(&bso, "\treloc %.8ux/%d %s %s+%#llx [%#llx]\n", (uint)(sym->value+r->off), r->siz, typ, rsname, r->add, r->sym->value+r->add);
  • 変更後: Bprint(&bso, "\treloc %.8ux/%d %s %s+%#llx [%#llx]\n", (uint)(sym->value+r->off), r->siz, typ, rsname, (vlong)r->add, (vlong)(r->sym->value+r->add));
    • Bprint関数への引数であるr->addr->sym->value+r->addが、それぞれ明示的に(vlong)型にキャストされました。これにより、%#llxというフォーマット指定子が期待する64ビット整数型と引数の型が一致し、Plan 9環境での「format mismatch」警告が解消されました。
  • 変更前: datsize = 0;
  • 変更後: (行削除)
    • dodata関数内で、datsizeという変数に0が代入されていましたが、このdatsizeはその後一切使用されていませんでした。この行を削除することで、「set and not used」という警告が解消されました。

これらの変更は、GoのツールチェインがPlan 9環境でよりクリーンにビルドされるようにするための、細かながらも重要な修正です。

関連リンク

参考にした情報源リンク