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

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

コミット

commit 8a28085a0fdfea041ff923353c7e482455322c2e
Author: Ian Lance Taylor <iant@golang.org>
Date:   Wed May 8 06:28:33 2013 -0700

    cmd/cgo: pass -Wsystem-headers when looking for errors
    
    This works around a bug in GCC 4.8.0.
    
    Fixes #5118.
    
    R=golang-dev, r, minux.ma
    CC=golang-dev
    https://golang.org/cl/9120045

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

https://github.com/golang/go/commit/8a28085a0fdfea041ff923353c7e482455322c2e

元コミット内容

このコミットは、Go言語のcmd/cgoツールにおいて、エラー検出時にGCCに-Wsystem-headersフラグを渡すように変更するものです。これは、GCC 4.8.0に存在する特定のバグを回避するための対応であり、Go issue #5118を修正します。

変更の背景

この変更の背景には、GCC (GNU Compiler Collection) のバージョン4.8.0に存在する既知のバグがあります。具体的には、GCC 4.8.0では、システムヘッダーファイル内で定義されたマクロによって生成された値に対して、-Wunused-value警告が適切に適用されない場合がありました。

cgoはGoプログラムからCコードを呼び出すためのツールであり、Cコンパイラ(通常はGCC)を利用してCコードをコンパイルします。cgoがCコードのエラーをチェックする際、GCCの警告オプションが適切に機能しないと、本来検出されるべき問題が見過ごされる可能性があります。

Go issue #5118は、このGCCのバグがcgoの動作に影響を与え、特定の状況下で不要な値に関する警告が抑制されてしまう問題として報告されました。この問題は、開発者がCgoコードの潜在的な問題を特定するのを困難にするため、修正が必要とされました。

-Wsystem-headersオプションを追加することで、GCCはシステムヘッダー内の警告も報告するようになります。これにより、GCC 4.8.0のバグによって抑制されていた警告が再び表示されるようになり、cgoがより正確にCコードのエラーを検出できるようになります。コミットメッセージにもあるように、この変更は追加の警告を生成する可能性がありますが、cgo-testファイル用にマークされていないエラーは無視されるため、全体的な影響は限定的です。

前提知識の解説

Go言語のcgo

cgoはGo言語のツールチェーンの一部であり、GoプログラムがC言語のコードを呼び出したり、C言語のコードからGoの関数を呼び出したりするためのメカニズムを提供します。GoとCの間の相互運用性を可能にし、既存のCライブラリをGoプロジェクトで利用する際に不可欠です。cgoは、Goのソースコード内にCコードを埋め込む特殊なコメントブロック(import "C"の直後)を解析し、GoとCの間のバインディングコードを生成します。このプロセスの一環として、cgoは内部的にCコンパイラ(通常はGCC)を呼び出して、埋め込まれたCコードをコンパイルし、エラーや警告をチェックします。

GCC (GNU Compiler Collection)

GCCは、GNUプロジェクトによって開発された、様々なプログラミング言語(C, C++, Objective-C, Fortran, Ada, Goなど)に対応するコンパイラの集合体です。ソフトウェア開発において広く利用されており、特にLinuxシステムでは標準的なコンパイラとして機能します。GCCは、コードのコンパイルだけでなく、様々な警告オプション(-Wで始まるオプション)を提供し、プログラマーが潜在的なバグや非推奨のコードパターンを特定するのに役立ちます。

GCCの警告オプション

GCCには、コードの品質や潜在的な問題を指摘するための多数の警告オプションがあります。

  • -Wunused-value: この警告は、計算された値が使用されずに破棄された場合に発行されます。例えば、関数呼び出しの戻り値が変数に代入されず、その値が後続の処理で利用されない場合などです。これは、プログラマーの意図しない動作や、リソースリークなどの潜在的なバグを示す可能性があります。
  • -Wsystem-headers: 通常、GCCはシステムヘッダーファイル(/usr/includeなどの標準パスにあるヘッダー)内の警告を抑制します。これは、システムヘッダーが通常は正しく、ユーザーがそれらの内容を修正できないためです。しかし、-Wsystem-headersオプションをGCCに渡すと、システムヘッダー内の警告も報告されるようになります。これは、コンパイラのバグを調査したり、特定の環境での問題をデバッグしたりする際に役立つことがあります。

Go issue #5118

Goプロジェクトでは、GitHubのIssueトラッカーを使用してバグ報告や機能リクエストを管理しています。Go issue #5118は、このコミットが修正しようとしている特定のバグ報告です。通常、Issueには問題の詳細な説明、再現手順、期待される動作、実際の動作などが含まれます。このIssueは、GCC 4.8.0の-Wunused-valueに関するバグがcgoのコンパイルプロセスに影響を与えていることを指摘していたと考えられます。

技術的詳細

このコミットは、src/cmd/cgo/gcc.goファイル内のgccErrors関数に一行の変更を加えるものです。gccErrors関数は、cgoがCコードのコンパイル時にGCCからエラーや警告を取得するために使用されます。

変更前は、gccErrors関数はp.gccCmd()によって生成されたGCCコマンドライン引数を使用していました。この引数には、CgoがCコードをコンパイルするために必要な基本的なオプションが含まれています。

変更後、args = append(args, "-Wsystem-headers")という行が追加されました。この行は、既存のGCCコマンドライン引数リストに-Wsystem-headersフラグを追加します。これにより、cgoがGCCを呼び出してCコードのエラーをチェックする際、GCCはシステムヘッダーファイル内の警告も報告するようになります。

コミットメッセージで言及されているように、この変更はGCC 4.8.0のバグに対するワークアラウンドです。このバグは、システムヘッダーで定義されたマクロによって生成された値に対して-Wunused-value警告が正しく適用されないというものでした。-Wsystem-headersを追加することで、GCCはこの警告を抑制しなくなり、cgoはより包括的なエラーチェックを実行できるようになります。

この変更は、cgoがCコードの潜在的な問題をより確実に検出できるようにすることで、GoとCの相互運用コードの堅牢性を向上させます。

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

src/cmd/cgo/gcc.goファイルのgccErrors関数に以下の変更が加えられました。

--- a/src/cmd/cgo/gcc.go
+++ b/src/cmd/cgo/gcc.go
@@ -809,6 +809,15 @@ func (p *Package) gccDefines(stdin []byte) string {
 func (p *Package) gccErrors(stdin []byte) string {
 	// TODO(rsc): require failure
 	args := p.gccCmd()
+
+	// GCC 4.8.0 has a bug: it sometimes does not apply
+	// -Wunused-value to values that are macros defined in system
+	// headers.  See issue 5118.  Adding -Wsystem-headers avoids
+	// that problem.  This will produce additional errors, but it
+	// doesn't matter because we will ignore all errors that are
+	// not marked for the cgo-test file.
+	args = append(args, "-Wsystem-headers")
+
 	if *debugGcc {
 		fmt.Fprintf(os.Stderr, "$ %s <<EOF\\n", strings.Join(args, " "))
 		os.Stderr.Write(stdin)

コアとなるコードの解説

変更されたのはsrc/cmd/cgo/gcc.go内のgccErrors関数です。

  1. args := p.gccCmd(): この行は、GCCを呼び出すための基本的なコマンドライン引数を取得します。これには、入力ファイル、出力ファイル、インクルードパスなどの標準的なコンパイルオプションが含まれています。
  2. 追加されたコードブロック:
    	// GCC 4.8.0 has a bug: it sometimes does not apply
    	// -Wunused-value to values that are macros defined in system
    	// headers.  See issue 5118.  Adding -Wsystem-headers avoids
    	// that problem.  This will produce additional errors, but it
    	// doesn't matter because we will ignore all errors that are
    	// not marked for the cgo-test file.
    	args = append(args, "-Wsystem-headers")
    
    このコメントは、変更の具体的な理由と目的を明確に説明しています。
    • GCC 4.8.0 has a bug: GCC 4.8.0のバグが原因であることを明示しています。
    • it sometimes does not apply -Wunused-value to values that are macros defined in system headers.: バグの具体的な内容を説明しています。システムヘッダー内のマクロによって生成された未使用の値に対する警告が機能しないという問題です。
    • See issue 5118.: 関連するGoのIssue番号を提示しており、詳細な背景情報を参照できるようにしています。
    • Adding -Wsystem-headers avoids that problem.: -Wsystem-headersオプションを追加することが、この問題を回避するための解決策であることを述べています。
    • This will produce additional errors, but it doesn't matter because we will ignore all errors that are not marked for the cgo-test file.: この変更が追加の警告を生成する可能性があることを認めつつも、cgoの内部的なエラー処理メカニズム(cgo-testファイル用にマークされていないエラーは無視される)により、その影響は問題ないことを説明しています。
  3. args = append(args, "-Wsystem-headers"): 実際に、GCCコマンドライン引数のスライスargsに文字列"-Wsystem-headers"を追加しています。これにより、gccErrors関数がGCCを呼び出す際に、このオプションが常に渡されるようになります。

この変更により、cgoはGCC 4.8.0の特定のバグによる警告の抑制を回避し、Cコードのより完全なエラーチェックを実行できるようになります。

関連リンク

参考にした情報源リンク