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(¤tStatus)` 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)
- src/door_lock.c:45: Consider adding DET check for invalid parameters
- src/door_lock.c:112: Magic number
3should be named constantCAN_ERROR_THRESHOLD - tests/test_door_lock.c:34: Add test case for CAN error recovery
- src/door_lock.h:15: Add Doxygen documentation for public API
- 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:
- Use AI review as first pass, human review for final approval
- Customize AI instructions for your coding standards
- Integrate into PR workflow for automatic reviews
- Track false positive rate and tune accordingly
- Do not rely solely on AI - human judgment remains essential