3.3: AI Code Review Tools

Overview

AI-powered code review tools analyze pull requests for bugs, security vulnerabilities, style violations, and architectural issues. They augment human reviewers by catching common issues automatically, allowing humans to focus on design and business logic.


AI Code Review Tool Landscape

Note: Pricing uses relative indicators ($ to $$$$) as of Q4 2024. Verify current pricing with vendors.

Tool AI Model Focus Areas Integration Cost
GitHub Copilot Chat GPT-4 Explain, improve, test VS Code, GitHub Included with Copilot
Amazon CodeGuru AWS ML Performance, security AWS, GitHub Pay-per-use
DeepCode (Snyk) Custom ML Security, bugs IDE, CI/CD Free-$$$
Codacy ML + rules Quality, security Git platforms $-$$$
CodeRabbit GPT-4 PR review, summaries GitHub, GitLab $$-$$$
Qodo (Codiumate) GPT-4 Test generation, review IDE $-$$

GitHub Copilot Chat for Code Review

Review Workflow

# In VS Code with Copilot Chat

# Select code block, then ask:
"Review this function for safety issues and MISRA compliance"

# Copilot analyzes and responds:

Copilot Response (illustrative example output format):

I found several issues in `DoorLockCtrl_MainFunction`:

1. MISRA C Rule 14.4 Violation (Line 12):
   - Using `if (retVal == RTE_E_OK)` is acceptable, but the enum comparison
     should use explicit check against defined values.

2. Potential NULL Pointer (Line 18):
   - `Rte_Read_PP_DoorStatus_Status(&currentStatus)` doesn't check return value.
   - Could read uninitialized data if CAN read fails.

3. Missing Bounds Check (Line 24):
   - `currentStatus` written without validating it's within valid range.

4. Race Condition (Line 7):
   - `canErrorCounter` is static but not protected by mutex in RTOS context.

Recommendations:
- Check all RTE return values
- Add input validation before writing status
- Use atomic operations or mutex for error counter
- Add DET (Development Error Trace) checks

Amazon CodeGuru Reviewer

Setup and Configuration

# .aws-codeguru-reviewer.yml
version: 1.0

RepositoryAnalysis:
  Java:
    Enabled: false
  Python:
    Enabled: true
    SourceCodeFiles:
      - "scripts/**/*.py"
  C:
    Enabled: true
    SourceCodeFiles:
      - "src/**/*.c"
      - "src/**/*.h"

CodeReview:
  Triggers:
    - PullRequest
    - OnDemand
  
  SecurityScanning:
    Enabled: true
    Severity:
      - Critical
      - High
      - Medium
  
  PerformanceAnalysis:
    Enabled: true
    Focus:
      - MemoryLeaks
      - ResourceLeaks
      - Deadlocks

Example CodeGuru Findings

"""
CodeGuru Finding: Resource Leak
File: src/file_handler.c
Line: 45
Severity: High

Description:
  File handle `fd` is opened but not closed on all code paths.
  If `process_data()` fails, the function returns without closing `fd`,
  leading to a resource leak.

Recommendation:
  Use RAII pattern or ensure `close(fd)` is called in all exit paths.
  
Code:
  int handle_file(const char* path) {
      int fd = open(path, O_RDONLY);  // <-- Opened here
      if (fd < 0) return -1;
      
      if (process_data(fd) < 0) {
          return -1;  // <-- Leak: fd not closed
      }
      
      close(fd);
      return 0;
  }

Suggested Fix:
  int handle_file(const char* path) {
      int fd = open(path, O_RDONLY);
      if (fd < 0) return -1;
      
      int result = process_data(fd);
      close(fd);  // <-- Always close
      
      return result;
  }
"""

DeepCode (Snyk Code) Integration

IDE Integration

// VS Code settings.json
{
  "snyk.enable": true,
  "snyk.severity": {
    "critical": true,
    "high": true,
    "medium": true,
    "low": false
  },
  "snyk.codeQuality": {
    "enable": true,
    "autoScan": true
  },
  "snyk.scanOnSave": true
}

Example Findings

/*
 * Snyk Finding: Improper NULL Check
 * Severity: Medium
 * CWE-476: NULL Pointer Dereference
 */

void process_buffer(uint8_t *buffer, uint16_t length) {
    // [WARN] Snyk: buffer could be NULL
    if (length > 0) {  // <-- Checks length but not buffer
        memset(buffer, 0, length);  // <-- Potential NULL deref
    }
}

// Recommended fix:
void process_buffer(uint8_t *buffer, uint16_t length) {
    if (buffer != NULL && length > 0) {  // [OK] Check both
        memset(buffer, 0, length);
    }
}

Automated PR Review Workflow

CodeRabbit Configuration

# .coderabbit.yaml
language: "en-US"
tone_instructions: "Be concise and technical. Focus on safety and MISRA compliance."

reviews:
  auto_review: true
  auto_incremental_review: true
  
  focus_areas:
    - security
    - performance
    - misra_c
    - memory_safety
  
  review_depth: "detailed"
  
  comment_style: "concise"
  
  ignore_patterns:
    - "**/*.md"
    - "**/generated/**"
    - "**/vendor/**"

knowledge_base:
  - "docs/coding_standards.md"
  - "docs/architecture.md"
  - "MISRA_C_2012.pdf"  # Note: Requires valid MISRA license

Example PR Review Output

## CodeRabbit Review Summary

**Files Changed**: 3
**Lines Added**: 127
**Lines Removed**: 45

### Critical Issues (2)

#### src/door_lock.c:67
**Issue**: Unchecked return value from CAN read
**Severity**: High
**Category**: Error Handling

```c
// Current code:
Rte_Read_PP_LockCommand_LockCmd(&lockCommand);
if (lockCommand == LOCK_CMD_LOCK) {
    // ...
}

Problem: If CAN read fails, lockCommand contains uninitialized data.

Recommendation:

retVal = Rte_Read_PP_LockCommand_LockCmd(&lockCommand);
if (retVal == RTE_E_OK && lockCommand == LOCK_CMD_LOCK) {
    // ...
}

src/door_lock.c:92

Issue: Static variable in reentrant function Severity: High Category: Concurrency

Problem: canErrorCounter is static but function may be called from multiple contexts.

Recommendation: Use atomic operations or move counter to component RAM.


Suggestions (5)

  1. src/door_lock.c:45: Consider adding DET check for invalid parameters
  2. src/door_lock.c:112: Magic number 3 should be named constant CAN_ERROR_THRESHOLD
  3. tests/test_door_lock.c:34: Add test case for CAN error recovery
  4. src/door_lock.h:15: Add Doxygen documentation for public API
  5. src/door_lock.c:78: Consider extracting error handling to separate function

Compliance Check

  • [PASS] MISRA C: 2 new violations fixed, 0 remaining
  • [PASS] Code coverage: 87% → 89% (+2%)
  • [WARN] Cyclomatic complexity: Function DoorLockCtrl_MainFunction = 11 (threshold: 10)
  • [PASS] No security vulnerabilities detected

---

## Custom AI Review Script

### Python Script Using OpenAI API

```python
"""
Custom AI Code Reviewer
Analyzes git diff and provides review comments
"""

import openai
import subprocess
from typing import List, Dict

class AICodeReviewer:
    def __init__(self, api_key: str):
        openai.api_key = api_key
        self.system_prompt = """
        You are an expert code reviewer for automotive embedded systems.
        Focus on:
        - MISRA C compliance
        - Safety (null checks, bounds checking)
        - Resource management (leaks, deadlocks)
        - AUTOSAR architecture violations
        - Performance issues for embedded targets
        
        Provide concise, actionable feedback.
        """
    
    def get_diff(self, base_branch: str = "main") -> str:
        """Get git diff for current branch."""
        result = subprocess.run(
            ["git", "diff", base_branch],
            capture_output=True,
            text=True
        )
        return result.stdout
    
    def review_diff(self, diff: str) -> Dict:
        """Send diff to AI for review."""
        response = openai.ChatCompletion.create(
            model="gpt-4",
            messages=[
                {"role": "system", "content": self.system_prompt},
                {"role": "user", "content": f"Review this code diff:\n\n{diff}"}
            ],
            temperature=0.3,
            max_tokens=2000
        )
        
        return {
            "review": response.choices[0].message.content,
            "tokens_used": response.usage.total_tokens
        }
    
    def review_file(self, file_path: str) -> Dict:
        """Review a specific file."""
        with open(file_path, 'r') as f:
            code = f.read()
        
        response = openai.ChatCompletion.create(
            model="gpt-4",
            messages=[
                {"role": "system", "content": self.system_prompt},
                {"role": "user", "content": f"Review this C code:\n\n{code}"}
            ],
            temperature=0.3
        )
        
        return {"review": response.choices[0].message.content}


# Usage in CI/CD
if __name__ == "__main__":
    import os
    
    reviewer = AICodeReviewer(api_key=os.getenv("OPENAI_API_KEY"))
    
    # Review current branch vs main
    diff = reviewer.get_diff("main")
    
    if diff:
        result = reviewer.review_diff(diff)
        print("=== AI Code Review ===")
        print(result["review"])
        print(f"\nTokens used: {result['tokens_used']}")
    else:
        print("No changes to review")

Summary

AI Code Review Tools enhance human review:

  • Automated Detection: Catch bugs, security issues, style violations
  • Consistency: Apply same standards to all PRs
  • Speed: Immediate feedback, no waiting for human reviewer
  • Learning: Improve over time from feedback
  • HITL Pattern: AI suggests, human approves or rejects

Best Practices:

  1. Use AI review as first pass, human review for final approval
  2. Customize AI instructions for your coding standards
  3. Integrate into PR workflow for automatic reviews
  4. Track false positive rate and tune accordingly
  5. Do not rely solely on AI - human judgment remains essential