構造化された SARIF 診断
MSVC コンパイラは、診断を SARIF (静的分析結果交換形式) として出力できます。 SARIF は、マシンで読み取り可能な JSON ベースの形式です。
MSVC コンパイラで SARIF 診断を生成するには、次の 2 つの方法があります。
/experimental:log
コマンド ラインでスイッチを渡します。 詳細については、 ドキュメントを/experimental:log
参照してください。- プログラムで起動
cl.exe
し、パイプをSARIF_OUTPUT_PIPE
介して SARIF ブロックを取得するように環境変数を設定します。
パイプを介した SARIF の取得
コンパイルの進行中に MSVC コンパイラから SARIF を使用するツールは、パイプを使用します。 Windows パイプの作成の詳細については、 CreatePipe
ドキュメントを参照してください。
パイプを介して SARIF を取得するには、環境変数を SARIF_OUTPUT_PIPE
UTF-16 でエンコードされた整数表現としてパイプの HANDLE
書き込み末尾に設定し、起動 cl.exe
します。 SARIF は、次のようにパイプに沿って送信されます。
- 新しい診断が使用可能になると、このパイプに書き込まれます。
- 診断は、SARIF オブジェクト全体としてではなく、一度に 1 つずつパイプに書き込まれます。
- 各診断は、Notification 型の JSON-RPC 2.0 メッセージで表されます。
- JSON-RPC メッセージの先頭
Content-Length
にヘッダーが付き、その後Content-Length: <N>
に 2 つの改行が続きます。これは<N>
、次の JSON-RPC メッセージの長さ (バイト単位) です。 - JSON-RPC メッセージとヘッダーはどちらも UTF-8 でエンコードされます。
- この JSON-RPC-with-header 形式は vs-streamjsonrpc と互換性があります。
- JSON-RPC 呼び出しのメソッド名は .
OnSarifResult
- この呼び出しには、パラメーター名でエンコードされたパラメーターが 1 つ含まれます
result
。 - 引数の値は、SARIF バージョン 2.1 標準で指定されている 1 つの
result
オブジェクトです。
例
JSON-RPC SARIF の結果 cl.exe
の例を次に示します。
Content-Length: 334
{"jsonrpc":"2.0","method":"OnSarifResult","params":{"result":{"ruleId":"C1034","level":"fatal","message":{"text":"iostream: no include path set"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"file:///C:/Users/sybrand/source/repos/cppcon-diag/cppcon-diag/cppcon-diag.cpp"},"region":{"startLine":1,"startColumn":10}}}]}}}{"jsonrpc":"2.0","method":"OnSarifResult","params":{"result":{"ruleId":"C1034","level":"fatal","message":{"text":"iostream: no include path set"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"file:///C:/Users/sybrand/source/repos/cppcon-diag/cppcon-diag/cppcon-diag.cpp"},"region":{"startLine":1,"startColumn":10}}}]}}}
SARIF の結果データ
コンパイラは、一部の診断の入れ子になった構造を表す追加情報を含む可能性がある SARIF を出力します。 診断 (SARIF オブジェクトで result
表される) には、そのフィールドに追加情報 relatedLocations
の "診断ツリー" が含まれている場合があります。 このツリーは、次のように SARIF プロパティ バッグ を使用してエンコードされます。
location
オブジェクトのproperties
フィールドには、診断ツリー内のこの場所の深さを値とするプロパティを含nestingLevel
める場合があります。 場所に指定されていない nestingLevel
場合、深さはあると見 0
なされ、この場所は、その場所を含むオブジェクトによって表されるルート診断の result
子になります。 それ以外の場合、値がフィールド内 relatedLocations
のこの場所の直前にある場所の深さを超える場合、この場所はその場所の子になります。 それ以外の場合、この場所は、同じ深度を持つフィールドのrelatedLocations
最も近い前location
の兄弟です。
例
次のコードがあるとします。
struct dog {};
struct cat {};
void pet(dog);
void pet(cat);
struct lizard {};
int main() {
pet(lizard{});
}
このコードがコンパイルされると、コンパイラによって次 result
のオブジェクトが生成されます (physicalLocation
簡潔にするためにプロパティが削除されています)。
{
"ruleId": "C2665",
"level": "error",
"message": {
"text": "'pet': no overloaded function could convert all the argument types"
},
"relatedLocations": [
{
"id": 0,
"message": {
"text": "could be 'void pet(cat)'"
}
},
{
"id": 1,
"message": {
"text": "'void pet(cat)': cannot convert argument 1 from 'lizard' to 'cat'"
},
"properties": {
"nestingLevel": 1
}
},
{
"id": 2,
"message": {
"text": "No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called"
},
"properties": {
"nestingLevel": 2
}
},
{
"id": 3,
"message": {
"text": "or 'void pet(dog)'"
}
},
{
"id": 4,
"message": {
"text": "'void pet(dog)': cannot convert argument 1 from 'lizard' to 'dog'"
},
"properties": {
"nestingLevel": 1
}
},
{
"id": 5,
"message": {
"text": "No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called"
},
"properties": {
"nestingLevel": 2
}
},
{
"id": 6,
"message": {
"text": "while trying to match the argument list '(lizard)'"
}
}
]
}
このresult
オブジェクト内のメッセージから生成される論理診断 ツリーは次のとおりです。
- 'pet': オーバーロードされた関数がすべての引数型を変換できませんでした
- 'void pet(cat)' である可能性があります
- 'void pet(cat)': 引数 1 を 'lizard' から 'cat' に変換できません
- この変換を実行できるユーザー定義変換演算子がない、または演算子を呼び出すことができない
- 'void pet(cat)': 引数 1 を 'lizard' から 'cat' に変換できません
- または 'void pet(dog)'
- 'void pet(dog)': 引数 1 を 'lizard' から 'dog' に変換できません
- この変換を実行できるユーザー定義変換演算子がない、または演算子を呼び出すことができない
- 'void pet(dog)': 引数 1 を 'lizard' から 'dog' に変換できません
- 引数リスト '(lizard)' と一致しようとしています
- 'void pet(cat)' である可能性があります
関連項目
フィードバック
https://aka.ms/ContentUserFeedback」を参照してください。
以下は間もなく提供いたします。2024 年を通じて、コンテンツのフィードバック メカニズムとして GitHub の issue を段階的に廃止し、新しいフィードバック システムに置き換えます。 詳細については、「フィードバックの送信と表示