# 帳票設計書 4-BugReporter

## 概要

本ドキュメントは、Clang Static Analyzerのバグレポート機能（BugReporter）の設計仕様を記載する。静的解析によるバグ検出結果をPathDiagnostics形式でレポート生成するクラス群である。

### 本帳票の処理概要

BugReporterは、Clang Static Analyzerが検出したバグ情報を収集し、開発者に理解しやすい形式の診断情報（PathDiagnostics）を生成するユーティリティクラスである。パス感度解析（Path-Sensitive Analysis）とパス非感度解析の両方に対応する。

**業務上の目的・背景**：静的解析ツールが検出したバグは、単にエラー箇所を示すだけでなく、どのような実行パスでそのバグに至るかを説明することが重要である。本機能は、解析エンジンが検出した潜在的なバグを、実行パス情報付きの診断レポートとして整形し、開発者がバグの根本原因を理解しやすくすることを目的とする。

**帳票の利用シーン**：Clang Static Analyzerによる静的解析実行時、コードレビュー時のバグ検証、CI/CDパイプラインでの品質ゲート、セキュリティ脆弱性スキャン時に利用される。

**主要な出力内容**：
1. バグの種類（BugType）と説明文
2. バグの発生箇所（ソースロケーション）
3. 実行パス情報（PathDiagnostic）
4. バグに関連するソース範囲（SourceRange）
5. Fix-itヒント（修正提案）
6. スタックヒント（関数呼び出し情報）

**帳票の出力タイミング**：Clang Static Analyzer（clang --analyze）実行時、またはscan-buildツール実行時にバグが検出された際に生成される。

**帳票の利用者**：ソフトウェア開発者、セキュリティエンジニア、QAエンジニア、コードレビュアー

## 帳票種別

診断レポート / バグレポート

## 利用画面

| 画面No | 画面名 | URL/ルーティング | 出力操作 |
|--------|--------|-----------------|---------|
| - | コマンドライン | `clang --analyze` | コマンド実行 |
| - | scan-build | `scan-build make` | ビルドラップ |

## 出力形式

### 基本仕様

| 項目 | 内容 |
|-----|------|
| ファイル形式 | PathDiagnosticConsumer依存（HTML/Plist/SARIF等） |
| 用紙サイズ | - |
| 向き | - |
| ファイル名 | Consumer依存 |
| 出力方法 | ファイル出力 / 標準出力 |
| 文字コード | UTF-8 |

### PathDiagnostic形式

| 項目 | 内容 |
|-----|------|
| パス情報 | 実行パスを構成するイベント列 |
| 注釈情報 | 各ステップでの説明文 |
| コードスニペット | 関連コード箇所 |

## 帳票レイアウト

### レイアウト概要

BugReportは内部データ構造であり、最終的なレイアウトはPathDiagnosticConsumerの実装に依存する。

```
┌─────────────────────────────────────────────────────────────────┐
│ BugReport                                                        │
│   ├─ BugType: バグの種類                                        │
│   ├─ Description: 詳細説明                                      │
│   ├─ ShortDescription: 短い説明                                 │
│   ├─ Location: 主要な位置                                       │
│   ├─ Ranges[]: 関連ソース範囲                                   │
│   ├─ Notes[]: 追加注釈                                          │
│   └─ Fixits[]: 修正提案                                         │
│                                                                  │
│ PathSensitiveBugReport (継承)                                   │
│   ├─ ErrorNode: ExplodedGraphノード                             │
│   ├─ InterestingSymbols: 注目シンボル                           │
│   ├─ InterestingRegions: 注目メモリ領域                         │
│   ├─ Callbacks[]: カスタムVisitor                               │
│   └─ StackHints: スタックヒント                                 │
└─────────────────────────────────────────────────────────────────┘
```

### BugReport基本項目

| No | 項目名 | 説明 | データ取得元 | 表示形式 |
|----|-------|------|-------------|---------|
| 1 | BugType | バグの種類 | BugType& BT | 文字列 |
| 2 | Description | 詳細な警告メッセージ | Description | 文字列（文で始まる） |
| 3 | ShortDescription | 短い警告メッセージ | ShortDescription | 文字列 |
| 4 | Location | バグの主要位置 | getLocation() | PathDiagnosticLocation |
| 5 | Ranges | 関連ソース範囲 | getRanges() | SourceRange配列 |
| 6 | Notes | 追加注釈 | getNotes() | PathDiagnosticNotePiece配列 |
| 7 | Fixits | 修正提案 | getFixits() | FixItHint配列 |

### PathSensitiveBugReport追加項目

| No | 項目名 | 説明 | データ取得元 | 表示形式 |
|----|-------|------|-------------|---------|
| 1 | ErrorNode | エラー発生ノード | ErrorNode | ExplodedNode* |
| 2 | InterestingSymbols | 注目シンボル | InterestingSymbols | DenseMap |
| 3 | InterestingRegions | 注目メモリ領域 | InterestingRegions | DenseMap |
| 4 | UniqueingLocation | 重複判定位置 | UniqueingLocation | PathDiagnosticLocation |
| 5 | Invalidations | 無効化情報 | Invalidations | SmallSet |

## 出力条件

### 抽出条件

| 条件名 | 説明 | 必須 |
|-------|------|-----|
| バグ検出 | 解析エンジンがバグを検出 | Yes |
| 抑制なし | BugSuppressionで抑制されていない | Yes |
| 有効なレポート | isValid() == true | Yes |

### ソート順

| 優先度 | 項目 | 昇順/降順 |
|-------|------|---------|
| 1 | 等価クラス | Profile()によるグループ化 |

### 重複排除条件

BugReportEquivClassにより、同じProfile()を持つレポートは1つにまとめられる。

## データベース参照仕様

### 参照データソース一覧

本帳票はデータベースを使用せず、解析エンジン（ExprEngine）の状態情報を参照する。

| データソース | 用途 | 取得方法 |
|-------------|------|---------|
| ExplodedGraph | 実行パス情報 | PathSensitiveBugReporter::getGraph() |
| ProgramState | プログラム状態 | ExplodedNode::getState() |
| SourceManager | ソース位置情報 | BugReporterData::getSourceManager() |

## 計算仕様

### 計算項目一覧

| 項目名 | 計算式 | 端数処理 | 備考 |
|-------|-------|---------|------|
| レポート等価性 | Profile()による比較 | - | FoldingSetNodeID |
| Interestingness | TrackingKindによる判定 | - | Thorough/Condition |

## 処理フロー

### 出力フロー

```mermaid
flowchart TD
    A[チェッカーがバグ検出] --> B[BugReport作成]
    B --> C[emitReport呼出]
    C --> D[EQClassesに追加]
    D --> E{等価クラス存在?}
    E -->|Yes| F[既存クラスに追加]
    E -->|No| G[新規クラス作成]
    F --> H[解析継続]
    G --> H
    H --> I[解析完了]
    I --> J[FlushReports呼出]
    J --> K[各EQClassについて]
    K --> L[findReportInEquivalenceClass]
    L --> M{有効なレポート?}
    M -->|No| N[スキップ]
    M -->|Yes| O[generateDiagnosticForConsumerMap]
    O --> P[PathDiagnostic生成]
    P --> Q[Consumer.HandlePathDiagnostic]
    N --> R{次のEQClass?}
    Q --> R
    R -->|Yes| K
    R -->|No| S[終了]
```

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 表示メッセージ | 対処方法 |
|----------|---------|--------------|---------|
| 無効化レポート | Invalidationsが空でない | (出力なし) | 正常動作（偽陽性排除） |
| パス生成失敗 | PathDiagnostic生成不可 | (出力なし) | スキップ |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定データ件数 | 解析対象コード量に依存 |
| 目標出力時間 | 解析時間に含まれる |
| 同時出力数上限 | Consumer数分 |

## セキュリティ考慮事項

- ソースコード断片がレポートに含まれる
- 潜在的なセキュリティ脆弱性情報が露出する可能性

## 備考

- BugReporterVisitorでカスタム診断メッセージを追加可能
- NoteTageでパス上の注釈を追加可能
- markInteresting()で注目すべきシンボル/リージョンを指定可能

---

## コードリーディングガイド

本帳票を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

BugReportのクラス階層とデータ構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | BugReporter.h | `clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h` | BugReport基底クラス（行119-249）の構造を理解 |
| 1-2 | BugReporter.h | 同上 | PathSensitiveBugReport派生クラス（行289-538）の追加メンバを理解 |

**読解のコツ**: BugReportは抽象基底クラスで、BasicBugReportとPathSensitiveBugReportの2種類の具象クラスがある。Kind enumで識別される。

#### Step 2: BugReporterクラスを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | BugReporter.h | `clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h` | BugReporterクラス（行586-682）のインターフェースを確認 |
| 2-2 | BugReporter.h | 同上 | PathSensitiveBugReporter派生クラス（行685-720）を確認 |

**主要処理フロー**:
1. **行646**: emitReport()でレポートを受け取る
2. **行597**: EQClassesでレポートをグループ化
3. **行610**: FlushReports()で最終出力

#### Step 3: 等価クラスを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | BugReporter.h | `clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h` | BugReportEquivClass（行544-563）の役割を確認 |

**主要処理フロー**:
- **行548**: Reportsベクターで同一等価クラスのレポートを保持
- **行559-562**: Profile()でFoldingSetNodeIDを計算

### プログラム呼び出し階層図

```
Checker (バグ検出)
    │
    └─ BugReporter::emitReport(BugReport)
           │
           ├─ EQClasses.FindNodeOrInsertPos()
           │      └─ BugReport::Profile()
           │
           ├─ BugReportEquivClass::AddReport()
           │
           └─ [解析完了後]
                  │
                  └─ FlushReports()
                         │
                         └─ FlushReport(EQClass)
                                │
                                ├─ findReportInEquivalenceClass()
                                │
                                └─ generateDiagnosticForConsumerMap()
                                       │
                                       └─ PathDiagnosticConsumer::HandlePathDiagnostic()
```

### データフロー図

```
[入力]                      [処理]                           [出力]

ExplodedGraph ──────▶ Checker検出
                           │
                           ▼
                    BugReport作成
                           │
                           ▼
                    emitReport()
                           │
                    ┌──────┴──────┐
                    ▼             ▼
            EQClasses      Invalidations
            (FoldingSet)   (偽陽性フィルタ)
                    │
                    ▼
               FlushReports()
                    │
                    ▼
          PathDiagnostic生成
                    │
                    ▼
          [HTML/Plist/SARIF等]
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| BugReporter.h | `clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h` | ヘッダ | BugReport, BugReporter, PathSensitiveBugReporterクラス定義 |
| BugReporter.cpp | `clang/lib/StaticAnalyzer/Core/BugReporter.cpp` | ソース | BugReporter実装 |
| BugReporterVisitors.h | `clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h` | ヘッダ | カスタムVisitorインターフェース |
| BugType.h | `clang/include/clang/StaticAnalyzer/Core/BugReporter/BugType.h` | ヘッダ | BugType定義 |
| PathDiagnostic.h | `clang/include/clang/Analysis/PathDiagnostic.h` | ヘッダ | PathDiagnostic構造定義 |
| BugSuppression.h | `clang/include/clang/StaticAnalyzer/Core/BugReporter/BugSuppression.h` | ヘッダ | 抑制機能 |
