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

[インデックス 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コンパイラによって生成される多数の警告を抱えていたことです。これらの警告は、コードの潜在的な問題点や非効率性を示唆しており、コンパイラの厳密なチェックによって表面化しました。

具体的には、以下のような種類の警告が挙げられます。

  1. non-interruptable temporary: 一時変数が割り込み可能なコンテキストで適切に扱われていない可能性を示唆します。これは、特に低レベルのシステムプログラミングにおいて、予期せぬ動作やデッドロックを引き起こす可能性があります。
  2. set and not used: 変数が宣言され、値が代入されているにもかかわらず、その値が後続のコードで一度も使用されていないことを示します。これは、デッドコード、ロジックの誤り、または単なるコードの冗長性を示唆し、コードの可読性や保守性を低下させます。
  3. format mismatch: printfsprintfのようなフォーマット文字列を使用する関数において、指定されたフォーマット指定子と、対応する引数のデータ型が一致しないことを示します。これは、未定義の動作を引き起こし、プログラムのクラッシュ、誤った出力、またはセキュリティ上の脆弱性につながる可能性があります。特に、VLONGというPlan 9特有の型が関係していることから、64ビット整数値の扱いに関する問題が示唆されます。
  4. overspecified class: GLOBL STATIC: C言語のストレージクラスに関する警告で、シンボルがGLOBL(グローバルリンケージ)とSTATIC(ファイルスコープリンケージ)の両方として指定されていることを意味します。これらは互いに排他的な概念であり、コンパイラがシンボルの可視性を正しく判断できない原因となります。通常、ファイル内で完結する関数や変数はstaticとして宣言されるべきであり、GLOBLは不要です。

これらの警告は、直接的なバグではないにしても、コードの品質、堅牢性、および将来の保守性に悪影響を及ぼす可能性があります。そのため、これらの警告を修正し、コードベースをクリーンに保つことが、Go言語の安定性と信頼性を維持するために重要でした。

前提知識の解説

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フォーマット指定子

printfsprintfなどの関数は、フォーマット文字列を使用して、引数を特定の形式で出力します。フォーマット指定子(例: %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->pccを更新するロジックを、より明確なブロックにまとめることで、一時的な値の扱いを改善しています。元のコードでは、c = p->pc = scan(...)という連鎖代入があり、これが特定のコンテキストで「非割り込み可能」と判断された可能性があります。修正後は、p->pcを先に更新し、その後にcp->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 で発生。printfsprintf関数において、フォーマット指定子と引数のデータ型が一致しないことを示します。特に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->pcunsigned long long型であるにもかかわらず、%uxunsigned int用)が使用されていたため、%lluxunsigned 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->sizer->addlong long型であるにもかかわらず、%dint用)が使用されていたため、%lldlong 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->offsetlong long型であるにもかかわらず、%dint用)が使用されていたため、%lldlong 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削除)

具体的なコアとなる変更箇所は以下の通りです。

  1. src/liblink/asm5.c:
    • 行479-485: checkpool呼び出し後のp->pccの更新ロジックの変更。
    • 行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 キーワードを追加。
  2. src/liblink/asm8.c:
    • 行1263, 1276: print関数のフォーマット指定子 %d から %lld への変更。
  3. src/liblink/list5.c:
    • 行150, 307: sprint関数のフォーマット指定子 %d から %lld への変更。
  4. src/liblink/obj6.c:
    • 行647: q = nil; の削除。
  5. src/liblink/pcln.c:
    • 行29-32: addvarint関数内のポインタ操作の変更 (*p++ = v; から *p = v; へ)。

コアとなるコードの解説

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->pccの両方に連鎖的に代入されていました。これは、一部のコンパイラ(特にPlan 9コンパイラ)が、この連鎖代入の途中で一時的な値が生成され、それが割り込みに対して安全でないと判断する可能性がありました。修正後は、まずp->pcscanの結果を代入し、その後にcp->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ビットのアドレス値を保持します。元のコードでは%uxunsigned int用)が使用されていましたが、これは32ビットの値を想定しています。p->pcが64ビット値である場合、%uxを使用すると値が切り捨てられたり、正しく表示されなかったりする可能性があります。%lluxunsigned 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->sizer->adda->offsetといった変数がlong long型であるにもかかわらず、%dint用)が使用されていたため、format mismatch警告が発生していました。これらを%lldlong 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言語のリンカのコードベースの品質と堅牢性を向上させ、潜在的なバグや未定義の動作を排除する上で重要な役割を果たしています。

関連リンク

参考にした情報源リンク