[インデックス 18060] ファイルの概要
このコミットは、Go言語のリンカであるliblink
内の複数のC言語ソースファイル(asm5.c
, asm8.c
, list5.c
, obj6.c
, pcln.c
)におけるPlan 9コンパイラからの警告を修正することを目的としています。これらの警告は、主に型とフォーマット指定子の不一致、未使用変数、およびストレージクラスの不適切な指定に関するものでした。本コミットにより、コードの品質と堅牢性が向上し、潜在的なバグや未定義の動作が排除されました。
コミット
commit 6e97513012581c8d5c2ee83defbecc8d93642ad4
Author: David du Colombier <0intro@gmail.com>
Date: Wed Dec 18 20:19:29 2013 +0100
liblink: fix Plan 9 warnings
warning: src/liblink/asm5.c:485 non-interruptable temporary
warning: src/liblink/asm5.c:565 set and not used: c
warning: src/liblink/asm5.c:622 format mismatch ux VLONG, arg 2
warning: src/liblink/asm5.c:1218 overspecified class: asmout GLOBL STATIC
warning: src/liblink/asm5.c:2088 overspecified class: oprrr GLOBL STATIC
warning: src/liblink/asm5.c:2202 overspecified class: opbra GLOBL STATIC
warning: src/liblink/asm5.c:2237 overspecified class: olr GLOBL STATIC
warning: src/liblink/asm5.c:2266 overspecified class: olhr GLOBL STATIC
warning: src/liblink/asm5.c:2291 overspecified class: osr GLOBL STATIC
warning: src/liblink/asm5.c:2302 overspecified class: oshr GLOBL STATIC
warning: src/liblink/asm5.c:2312 overspecified class: osrr GLOBL STATIC
warning: src/liblink/asm5.c:2319 overspecified class: oshrr GLOBL STATIC
warning: src/liblink/asm5.c:2325 overspecified class: olrr GLOBL STATIC
warning: src/liblink/asm5.c:2332 overspecified class: olhrr GLOBL STATIC
warning: src/liblink/asm5.c:2338 overspecified class: ofsr GLOBL STATIC
warning: src/liblink/asm5.c:2375 overspecified class: omvl GLOBL STATIC
warning: src/liblink/asm8.c:1261 format mismatch d VLONG, arg 3
warning: src/liblink/asm8.c:1274 format mismatch +d VLONG, arg 5
warning: src/liblink/list5.c:153 format mismatch d VLONG, arg 3
warning: src/liblink/list5.c:310 format mismatch d VLONG, arg 3
warning: src/liblink/obj6.c:665 set and not used: q
warning: src/liblink/pcln.c:32 set and not used: p
R=golang-dev, jas, gobot, rsc
CC=golang-dev
https://golang.org/cl/40370043
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/6e97513012581c8d5c2ee83defbecc8d93642ad4
元コミット内容
上記の「コミット」セクションに記載されている内容と同一です。
変更の背景
このコミットの主な背景は、Go言語のツールチェインの一部であるliblink
(リンカ)が、Plan 9コンパイラによって生成される多数の警告を抱えていたことです。これらの警告は、コードの潜在的な問題点や非効率性を示唆しており、コンパイラの厳密なチェックによって表面化しました。
具体的には、以下のような種類の警告が挙げられます。
non-interruptable temporary
: 一時変数が割り込み可能なコンテキストで適切に扱われていない可能性を示唆します。これは、特に低レベルのシステムプログラミングにおいて、予期せぬ動作やデッドロックを引き起こす可能性があります。set and not used
: 変数が宣言され、値が代入されているにもかかわらず、その値が後続のコードで一度も使用されていないことを示します。これは、デッドコード、ロジックの誤り、または単なるコードの冗長性を示唆し、コードの可読性や保守性を低下させます。format mismatch
:printf
やsprintf
のようなフォーマット文字列を使用する関数において、指定されたフォーマット指定子と、対応する引数のデータ型が一致しないことを示します。これは、未定義の動作を引き起こし、プログラムのクラッシュ、誤った出力、またはセキュリティ上の脆弱性につながる可能性があります。特に、VLONG
というPlan 9特有の型が関係していることから、64ビット整数値の扱いに関する問題が示唆されます。overspecified class: GLOBL STATIC
: C言語のストレージクラスに関する警告で、シンボルがGLOBL
(グローバルリンケージ)とSTATIC
(ファイルスコープリンケージ)の両方として指定されていることを意味します。これらは互いに排他的な概念であり、コンパイラがシンボルの可視性を正しく判断できない原因となります。通常、ファイル内で完結する関数や変数はstatic
として宣言されるべきであり、GLOBL
は不要です。
これらの警告は、直接的なバグではないにしても、コードの品質、堅牢性、および将来の保守性に悪影響を及ぼす可能性があります。そのため、これらの警告を修正し、コードベースをクリーンに保つことが、Go言語の安定性と信頼性を維持するために重要でした。
前提知識の解説
Goコンパイラとリンカ (liblink)
Go言語のビルドプロセスは、ソースコードを機械語に変換し、実行可能なバイナリを生成する一連のステップを含みます。このプロセスにおいて、リンカは非常に重要な役割を担います。
- コンパイラ: Goのソースコード(
.go
ファイル)を、各アーキテクチャ(例: x86-64, ARM)に対応したアセンブリコードやオブジェクトファイルに変換します。 - リンカ (liblink): Goのツールチェインにおけるリンカは、
liblink
として知られるC言語で書かれたライブラリ群です。これは、コンパイラが生成した複数のオブジェクトファイルやライブラリを結合し、最終的な実行可能ファイルや共有ライブラリを生成する役割を担います。具体的には、シンボルの解決(あるファイルで定義された関数や変数を別のファイルから参照できるようにする)、再配置(アドレスの調整)、および最終的なバイナリのレイアウト決定などを行います。Goの初期のリンカは、Plan 9のリンカの設計思想を強く受け継いでいました。
Plan 9
Plan 9 from Bell Labsは、ベル研究所で開発された分散オペレーティングシステムです。Go言語の開発者の一部(Rob Pike, Ken Thompsonなど)は、Plan 9の開発にも深く関わっていました。このため、Go言語の設計思想やツールチェインには、Plan 9の影響が色濃く反映されています。
- Plan 9のツールチェイン: Plan 9は独自のコンパイラ、アセンブラ、リンカなどのツールチェインを持っていました。これらのツールは、非常に厳密なコーディング規約やセマンティクスを強制することがあり、一般的なGCCなどのコンパイラとは異なる警告やエラーを生成することがあります。本コミットで修正された警告は、まさにPlan 9コンパイラの特性に起因するものです。
C言語のストレージクラス (static, global)
C言語において、変数のスコープ(可視範囲)とリンケージ(結合性)を制御するために「ストレージクラス」という概念があります。
static
:- 関数スコープ内: ローカル変数を
static
と宣言すると、その変数はプログラムの実行期間中メモリに存在し続けますが、その変数を参照できるのは宣言された関数内のみです。 - ファイルスコープ内: グローバル変数や関数を
static
と宣言すると、その変数や関数は宣言されたファイル内でのみ可視となります(内部リンケージ)。他のファイルからは参照できません。これは、コードのモジュール性を高め、名前の衝突を防ぐために非常に有用です。
- 関数スコープ内: ローカル変数を
extern
(暗黙的または明示的):- デフォルトでは、ファイルスコープで宣言された変数や関数は外部リンケージを持ちます。つまり、他のファイルからも参照可能です。これを明示的に示すために
extern
キーワードを使用することもありますが、通常は省略されます。
- デフォルトでは、ファイルスコープで宣言された変数や関数は外部リンケージを持ちます。つまり、他のファイルからも参照可能です。これを明示的に示すために
GLOBL
(Plan 9特有): Plan 9のコンパイラやアセンブラにおいて、シンボルがグローバルリンケージを持つことを示すためのキーワードです。本コミットの警告overspecified class: GLOBL STATIC
は、このGLOBL
とC言語のstatic
が同時に指定されているという矛盾を指摘しています。ファイルスコープでstatic
と宣言された関数は、外部から参照されるべきではないため、GLOBL
の指定は不要であり、矛盾しています。
C言語のprintf/sprintfフォーマット指定子
printf
やsprintf
などの関数は、フォーマット文字列を使用して、引数を特定の形式で出力します。フォーマット指定子(例: %d
, %s
, %x
)は、対応する引数のデータ型と厳密に一致している必要があります。
%d
: 符号付き10進整数(int
型)%lld
: 符号付き10進長々整数(long long int
型)%u
: 符号なし10進整数(unsigned int
型)%x
: 符号なし16進整数(unsigned int
型)%llx
: 符号なし16進長々整数(unsigned long long int
型)%p
: ポインタのアドレス(通常は16進数)
型とフォーマット指定子が一致しない場合、コンパイラは警告を生成し、実行時には未定義の動作(例: メモリの不正アクセス、ゴミ値の出力)が発生する可能性があります。本コミットでは、特に64ビット整数値(long long
)を扱う際に、適切なフォーマット指定子(%lld
, %llux
)が使用されていなかった問題が修正されています。
技術的詳細
このコミットは、Go言語のリンカliblink
のC言語ソースコードにおける、Plan 9コンパイラが検出した複数の警告を体系的に修正しています。それぞれの警告タイプと、それに対する具体的な修正内容を以下に詳述します。
1. non-interruptable temporary
警告の修正
- 警告内容:
src/liblink/asm5.c:485
およびsrc/liblink/pcln.c:32
で発生。一時変数が割り込み可能なコンテキストで適切に扱われていない可能性を示唆。これは、特に低レベルのコードで、割り込みが発生した際に一時変数の状態が保証されない場合に問題となります。 asm5.c
での修正:
この修正は、--- a/src/liblink/asm5.c +++ b/src/liblink/asm5.c @@ -479,8 +479,10 @@ span5(Link *ctxt, LSym *cursym) m = o->size; // must check literal pool here in case p generates many instructions if(ctxt->blitrl){ - if(checkpool(ctxt, op, p->as == ACASE ? casesz(ctxt, p) : m)) - c = p->pc = scan(ctxt, op, p, c); + if(checkpool(ctxt, op, p->as == ACASE ? casesz(ctxt, p) : m)) { + p->pc = scan(ctxt, op, p, c); + c = p->pc; + } } if(m == 0 && (p->as != AFUNCDATA && p->as != APCDATA)) { ctxt->diag("zero-width instruction\n%P", p);
checkpool
の呼び出し結果に基づいてp->pc
とc
を更新するロジックを、より明確なブロックにまとめることで、一時的な値の扱いを改善しています。元のコードでは、c = p->pc = scan(...)
という連鎖代入があり、これが特定のコンテキストで「非割り込み可能」と判断された可能性があります。修正後は、p->pc
を先に更新し、その後にc
にp->pc
の値を代入することで、処理の順序と一時変数のライフサイクルがより明確になっています。pcln.c
での修正:--- a/src/liblink/pcln.c +++ b/src/liblink/pcln.c @@ -29,7 +29,7 @@ addvarint(Link *ctxt, Pcdata *d, uint32 val) p = d->p + d->n; for(v = val; v >= 0x80; v >>= 7) *p++ = v | 0x80; - *p++ = v; + *p = v; d->n += n; }
addvarint
関数は、可変長整数(varint)をバイト列にエンコードする処理を行っています。元のコードの*p++ = v;
は、ループの最後に残ったv
の値をp
が指すアドレスに書き込み、その後p
をインクリメントしていました。しかし、このp
のインクリメントが、次の処理でd->n
を更新する際に不要、あるいは誤ったポインタ位置を指す原因となっていた可能性があります。修正後の*p = v;
は、v
の値を書き込むだけでp
をインクリメントしないため、ポインタの最終位置が正しく保たれ、警告が解消されています。これは、d->n
の更新がp
の最終位置に依存している場合に特に重要です。
2. set and not used
警告の修正
- 警告内容:
src/liblink/asm5.c:565
(c
変数) およびsrc/liblink/obj6.c:665
(q
変数),src/liblink/pcln.c:32
(p
変数) で発生。変数が宣言され、値が代入されているにもかかわらず、その値が後続のコードで一度も使用されていないことを示します。これはデッドコードであり、コンパイラが最適化の対象としますが、警告として開発者に通知されます。 asm5.c
での修正:--- a/src/liblink/asm5.c +++ b/src/liblink/asm5.c @@ -560,8 +562,6 @@ span5(Link *ctxt, LSym *cursym) cursym->size = c; } while(bflag); - c += c&4; - /* * lay out the code. all the pc-relative code references, * even cross-function, are resolved now;
c += c&4;
という行が削除されています。この行は、c
の値を4バイト境界にアラインメントしようとしていた可能性がありますが、その結果が後続のコードで利用されていなかったため、未使用変数c
に関する警告が発生していました。この行を削除することで、警告が解消され、コードの冗長性が排除されました。obj6.c
での修正:--- a/src/liblink/obj6.c +++ b/src/liblink/obj6.c @@ -647,7 +647,6 @@ stacksplit(Link *ctxt, Prog *p, int32 framesize, int32 textarg, Prog **jmpok) q1->pcond = p; }\n - q = nil; q1 = nil; if(framesize <= StackSmall) { // small stack: SP <= stackguard
q = nil;
という行が削除されています。変数q
は宣言されていますが、この行でnil
が代入された後、後続のコードで利用されていなかったため、警告が発生していました。この行を削除することで、未使用変数に関する警告が解消されました。
3. format mismatch
警告の修正
- 警告内容:
src/liblink/asm5.c:622
,src/liblink/asm8.c:1261
,src/liblink/asm8.c:1274
,src/liblink/list5.c:153
,src/liblink/list5.c:310
で発生。printf
やsprintf
関数において、フォーマット指定子と引数のデータ型が一致しないことを示します。特にVLONG
というPlan 9特有の型が関係しており、これは通常64ビット整数を指します。 asm5.c
での修正:--- a/src/liblink/asm5.c +++ b/src/liblink/asm5.c @@ -617,7 +617,7 @@ flushpool(Link *ctxt, Prog *p, int skip, int force) if(ctxt->blitrl) { if(skip){ - if(0 && skip==1)print("note: flush literal pool at %ux: len=%ud ref=%ux\n", p->pc+4, pool.size, pool.start); + if(0 && skip==1)print("note: flush literal pool at %llux: len=%ud ref=%ux\n", p->pc+4, pool.size, pool.start); q = ctxt->arch->prg(); q->as = AB; q->to.type = D_BRANCH;
p->pc
がunsigned long long
型であるにもかかわらず、%ux
(unsigned int
用)が使用されていたため、%llux
(unsigned long long
用)に修正されました。これにより、64ビットアドレスが正しく出力されるようになります。asm8.c
での修正:--- a/src/liblink/asm8.c +++ b/src/liblink/asm8.c @@ -1263,7 +1263,7 @@ span8(Link *ctxt, LSym *s) s->size = c; if(0 /* debug['a'] > 1 */) { - print("span1 %s %d (%d tries)\\n %.6ux", s->name, s->size, n, 0); + print("span1 %s %lld (%d tries)\\n %.6ux", s->name, s->size, n, 0); for(i=0; i<s->np; i++) { print(" %.2ux", s->p[i]); if(i%16 == 15) @@ -1276,7 +1276,7 @@ span8(Link *ctxt, LSym *s) Reloc *r; r = &s->r[i]; - print(" rel %#.4ux/%d %s%+d\\n", r->off, r->siz, r->sym->name, r->add); + print(" rel %#.4ux/%d %s%+lld\\n", r->off, r->siz, r->sym->name, r->add); } } }
s->size
とr->add
がlong long
型であるにもかかわらず、%d
(int
用)が使用されていたため、%lld
(long long
用)に修正されました。これにより、これらの64ビット整数値が正しく出力されるようになります。list5.c
での修正:--- a/src/liblink/list5.c +++ b/src/liblink/list5.c @@ -150,7 +150,7 @@ Dconv(Fmt *fp) break; case D_CONST2: - sprint(str, "$%d-%d", a->offset, a->offset2); + sprint(str, "$%lld-%d", a->offset, a->offset2); break; case D_SHIFT: @@ -307,7 +307,7 @@ Nconv(Fmt *fp) break; case D_NONE: - sprint(str, "%d", a->offset); + sprint(str, "%lld", a->offset); break; case D_EXTERN:
a->offset
がlong long
型であるにもかかわらず、%d
(int
用)が使用されていたため、%lld
(long long
用)に修正されました。これにより、オフセット値が正しく文字列に変換されるようになります。
4. overspecified class: GLOBL STATIC
警告の修正
- 警告内容:
src/liblink/asm5.c
内の複数の関数(asmout
,oprrr
,opbra
,olr
,olhr
,osr
,oshr
,osrr
,oshrr
,olrr
,olhrr
,ofsr
,omvl
)で発生。これらの関数がGLOBL
(グローバルリンケージ)とSTATIC
(ファイルスコープリンケージ)の両方として指定されているという矛盾を指摘。 asm5.c
での修正:
警告対象となっていたすべての関数宣言に--- a/src/liblink/asm5.c +++ b/src/liblink/asm5.c @@ -1212,7 +1212,7 @@ buildop(Link *ctxt) }\n }\n \n-void +static void asmout(Link *ctxt, Prog *p, Optab *o, int32 *out, LSym *gmsym) {\n int32 o1, o2, o3, o4, o5, o6, v;\n ... (同様の修正が他の関数にも適用) ...
static
キーワードが追加されました。これにより、これらの関数はファイルスコープの内部リンケージを持つことになり、GLOBL
という矛盾した指定が解消されます。これは、これらの関数がasm5.c
ファイル内でのみ使用されることを意図しているため、適切な修正です。static
キーワードの追加は、コンパイラの警告を解消するだけでなく、コードのモジュール性を高め、不必要なグローバルシンボルを減らすという良いプラクティスにも合致します。
これらの修正は、Go言語のリンカのコードベースの品質と堅牢性を向上させ、将来的なメンテナンスを容易にする上で重要な役割を果たしています。
コアとなるコードの変更箇所
このコミットでは、主に以下のファイルが変更されています。
src/liblink/asm5.c
: 36行変更 (18挿入, 18削除)src/liblink/asm8.c
: 4行変更 (2挿入, 2削除)src/liblink/list5.c
: 4行変更 (2挿入, 2削除)src/liblink/obj6.c
: 1行変更 (0挿入, 1削除)src/liblink/pcln.c
: 2行変更 (1挿入, 1削除)
具体的なコアとなる変更箇所は以下の通りです。
src/liblink/asm5.c
:- 行479-485:
checkpool
呼び出し後のp->pc
とc
の更新ロジックの変更。 - 行560-562:
c += c&4;
の削除。 - 行617-622:
print
関数のフォーマット指定子%ux
から%llux
への変更。 - 行1212, 2082, 2196, 2231, 2260, 2285, 2296, 2306, 2312, 2319, 2325, 2332, 2338, 2369: 複数の関数宣言に
static
キーワードを追加。
- 行479-485:
src/liblink/asm8.c
:- 行1263, 1276:
print
関数のフォーマット指定子%d
から%lld
への変更。
- 行1263, 1276:
src/liblink/list5.c
:- 行150, 307:
sprint
関数のフォーマット指定子%d
から%lld
への変更。
- 行150, 307:
src/liblink/obj6.c
:- 行647:
q = nil;
の削除。
- 行647:
src/liblink/pcln.c
:- 行29-32:
addvarint
関数内のポインタ操作の変更 (*p++ = v;
から*p = v;
へ)。
- 行29-32:
コアとなるコードの解説
src/liblink/asm5.c
-
span5
関数内のcheckpool
関連の修正:// 修正前 if(checkpool(ctxt, op, p->as == ACASE ? casesz(ctxt, p) : m)) c = p->pc = scan(ctxt, op, p, c); // 修正後 if(checkpool(ctxt, op, p->as == ACASE ? casesz(ctxt, p) : m)) { p->pc = scan(ctxt, op, p, c); c = p->pc; }
この変更は、
non-interruptable temporary
警告への対応です。元のコードでは、scan
関数の戻り値がp->pc
とc
の両方に連鎖的に代入されていました。これは、一部のコンパイラ(特にPlan 9コンパイラ)が、この連鎖代入の途中で一時的な値が生成され、それが割り込みに対して安全でないと判断する可能性がありました。修正後は、まずp->pc
にscan
の結果を代入し、その後にc
にp->pc
の値を代入することで、処理の順序を明確にし、一時変数のライフサイクルをより制御可能にしています。これにより、警告が解消され、コードの堅牢性が向上します。 -
c += c&4;
の削除:--- a/src/liblink/asm5.c +++ b/src/liblink/asm5.c @@ -560,8 +562,6 @@ span5(Link *ctxt, LSym *cursym) cursym->size = c; } while(bflag); - c += c&4; - /* * lay out the code. all the pc-relative code references,\n
この行は、
c
の値を4バイト境界にアラインメントしようとしていた可能性がありますが、その結果が後続のコードで利用されていなかったため、set and not used
警告が発生していました。この行を削除することで、デッドコードが排除され、警告が解消されます。 -
print
関数のフォーマット指定子の修正:--- a/src/liblink/asm5.c +++ b/src/liblink/asm5.c @@ -617,7 +617,7 @@ flushpool(Link *ctxt, Prog *p, int skip, int force) if(ctxt->blitrl) { if(skip){ - if(0 && skip==1)print("note: flush literal pool at %ux: len=%ud ref=%ux\n", p->pc+4, pool.size, pool.start); + if(0 && skip==1)print("note: flush literal pool at %llux: len=%ud ref=%ux\n", p->pc+4, pool.size, pool.start); q = ctxt->arch->prg(); q->as = AB; q->to.type = D_BRANCH;
p->pc
はプログラムカウンタであり、通常は64ビットのアドレス値を保持します。元のコードでは%ux
(unsigned int
用)が使用されていましたが、これは32ビットの値を想定しています。p->pc
が64ビット値である場合、%ux
を使用すると値が切り捨てられたり、正しく表示されなかったりする可能性があります。%llux
(unsigned long long
用)に修正することで、64ビットのアドレス値が正確に表示されるようになり、format mismatch
警告が解消されます。 -
関数宣言への
static
キーワードの追加:--- a/src/liblink/asm5.c +++ b/src/liblink/asm5.c @@ -1212,7 +1212,7 @@ buildop(Link *ctxt) }\n }\n \n-void +static void asmout(Link *ctxt, Prog *p, Optab *o, int32 *out, LSym *gmsym) {\n int32 o1, o2, o3, o4, o5, o6, v;\n
asmout
やその他の多くの関数にstatic
キーワードが追加されています。これは、これらの関数がasm5.c
ファイル内でのみ使用されることを意図しているにもかかわらず、Plan 9コンパイラがGLOBL STATIC
という矛盾したストレージクラスの指定を検出していたためです。static
を追加することで、これらの関数はファイルスコープの内部リンケージを持つことになり、外部からは参照できなくなります。これにより、overspecified class
警告が解消され、コードのモジュール性が向上します。
src/liblink/asm8.c
および src/liblink/list5.c
print
/sprint
関数のフォーマット指定子の修正:--- a/src/liblink/asm8.c +++ b/src/liblink/asm8.c @@ -1263,7 +1263,7 @@ span8(Link *ctxt, LSym *s) s->size = c; if(0 /* debug['a'] > 1 */) { - print("span1 %s %d (%d tries)\\n %.6ux", s->name, s->size, n, 0); + print("span1 %s %lld (%d tries)\\n %.6ux", s->name, s->size, n, 0); for(i=0; i<s->np; i++) { print(" %.2ux", s->p[i]); if(i%16 == 15) @@ -1276,7 +1276,7 @@ span8(Link *ctxt, LSym *s) Reloc *r; r = &s->r[i]; - print(" rel %#.4ux/%d %s%+d\\n", r->off, r->siz, r->sym->name, r->add); + print(" rel %#.4ux/%d %s%+lld\\n", r->off, r->siz, r->sym->name, r->add); } } }
s->size
やr->add
、a->offset
といった変数がlong long
型であるにもかかわらず、%d
(int
用)が使用されていたため、format mismatch
警告が発生していました。これらを%lld
(long long
用)に修正することで、64ビット整数値が正しく出力または文字列に変換されるようになります。これは、特に大きなファイルサイズやオフセットを扱うリンカにおいて、数値の正確な表現を保証するために不可欠です。
src/liblink/obj6.c
q = nil;
の削除:
変数--- a/src/liblink/obj6.c +++ b/src/liblink/obj6.c @@ -647,7 +647,6 @@ stacksplit(Link *ctxt, Prog *p, int32 framesize, int32 textarg, Prog **jmpok) q1->pcond = p; }\n - q = nil; q1 = nil; if(framesize <= StackSmall) { // small stack: SP <= stackguard
q
は宣言されていますが、この行でnil
が代入された後、後続のコードで利用されていなかったため、set and not used
警告が発生していました。この行を削除することで、未使用変数に関する警告が解消され、コードの冗長性が排除されます。
src/liblink/pcln.c
addvarint
関数内のポインタ操作の修正:--- a/src/liblink/pcln.c +++ b/src/liblink/pcln.c @@ -29,7 +29,7 @@ addvarint(Link *ctxt, Pcdata *d, uint32 val) p = d->p + d->n; for(v = val; v >= 0x80; v >>= 7) *p++ = v | 0x80; - *p++ = v; + *p = v; d->n += n; }
addvarint
関数は、可変長整数をバイト列にエンコードし、d->p
が指すバッファに書き込みます。ループの最後に残ったv
の値を書き込む際に、元のコードでは*p++ = v;
としていました。これは、v
を書き込んだ後にポインタp
をインクリメントします。しかし、このインクリメントが、その後のd->n += n;
によるバッファサイズの更新と整合性が取れていなかった可能性があります。修正後の*p = v;
は、v
を書き込むだけでp
をインクリメントしないため、p
が指す最終位置が正しく保たれ、d->n
の更新が正確に行われるようになります。これにより、non-interruptable temporary
警告(または関連するポインタ操作の警告)が解消されます。
これらの変更は、Go言語のリンカのコードベースの品質と堅牢性を向上させ、潜在的なバグや未定義の動作を排除する上で重要な役割を果たしています。
関連リンク
- Go言語公式ウェブサイト: https://golang.org/
- Go言語のツールチェインに関するドキュメント (Go 1.4時点のリンカの設計に関する情報が含まれる可能性): https://golang.org/doc/
- Plan 9 from Bell Labs: https://9p.io/plan9/
- C言語のストレージクラスに関する一般的な情報: https://www.tutorialspoint.com/cprogramming/c_storage_classes.htm
- C言語のprintfフォーマット指定子に関する一般的な情報: https://www.cplusplus.com/reference/cstdio/printf/
参考にした情報源リンク
- Go言語のコミット履歴 (GitHub): https://github.com/golang/go/commits/master
- Go言語のコードレビューシステム (Gerrit): https://go-review.googlesource.com/ (コミットメッセージに記載されている
https://golang.org/cl/40370043
は、Gerritの変更リストへのリンクです。) - C言語のコンパイラ警告に関する一般的な情報 (Stack Overflowなど): https://stackoverflow.com/
- Plan 9のコンパイラに関する情報 (Plan 9のドキュメントや関連フォーラム): https://9p.io/plan9/man/
- Go言語のリンカの内部構造に関する議論やドキュメント (Goのメーリングリストやデザインドキュメント): https://groups.google.com/g/golang-dev
- Go言語のソースコード: https://github.com/golang/go