Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Starting static analysis with Go

Sponsored · Your Podcast. Everywhere. Effortlessly. Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
Avatar for Tsuji Daishiro Tsuji Daishiro
November 13, 2021

Starting static analysis with Go

Go Conference 2021 Autumn のセッションで使用した資料です。
- セッションの詳細: https://gocon.jp/2021autumn/sessions/go-static-analysis/
- 発表者: https://twitter.com/d_tutuz

資料に誤りがあればtwitterでご連絡ください。

Avatar for Tsuji Daishiro

Tsuji Daishiro

November 13, 2021
Tweet

More Decks by Tsuji Daishiro

Other Decks in Technology

Transcript

  1. analysis パッケージの中心的な構造体 • analysis.Pass ◦ 静的解析に使う情報を扱う構造体 ◦ analysis.Pass を利用することでパッケージの情報や型、抽象構文木のトラ バース結果が簡単に手に入る!

    type Pass struct { // ... Pkg *types.Package // パッケージに関する情報 TypesInfo *types.Info // 抽象構文木の型に関する情報 // ... ResultOf map[*Analyzer]interface{} // 解析器をキーにした解析結果を保持 // ... }
  2. unmarshal モジュールで静的解析する流れ • Goのお手本の実装例を見るのがおすすめ ◦ unmarshal モジュール ◦ https://pkg.go.dev/golang.org/x/[email protected]/go/analysis/passes/unm arshal

    • 例:JSON のデコード ◦ json.Unmarshal や (*"encoding/json".Decoder).Decodeでは引数はポイ ンタ型である必要がある ◦ 引数がポインタ型でない場合は実行時エラー ◦ 静的解析(unmarshal モジュール)で引数の型をチェックできる
  3. unmarshal モジュールの実装 1. PreOrder(深さ優先探索)で抽象構文木の解析結果を取得 2. ノードがレシーバを保持しているかチェック 3. ノードの名前が Unmarshal か

    Decode であるかチェック 4. 関数呼び出しノードの引数の型情報を取得。ポインタ型やイン ターフェース型の場合はOK
  4. unmarshal モジュールの実装 (コア実装は70行程度) 1. PreOrder(深さ優先探索)で抽象構文木の解析結果を取得 → Pass.ResultOf の利用 2. ノードがレシーバを保持しているかチェック

    → Pass.ResultOf と Pass.TypesInfo の利用 3. ノードの名前が Unmarshal か Decode であるかチェック → Pass.ResultOf と Pass.TypesInfo の利用 4. 型情報から関数呼び出しノードの引数の型情報を取得。ポイ ンタ型やインターフェース型の場合はOK → Pass.ResultOf と Pass.TypesInfo の利用 Pass 構造体のフィールドを利用してロジックを実装できる