| name | check-memory-safety |
| description | Check Mojo code for memory safety issues (ownership violations, use-after-free, etc.). Use to catch memory bugs. |
| category | mojo |
| mcp_fallback | none |
Check Memory Safety
Validate Mojo code for memory safety violations and ownership issues.
When to Use
- Code review focused on memory safety
- Testing for use-after-free issues
- Verifying ownership transfer correctness
- Catching double-free or segmentation fault sources
- Validating SIMD memory access patterns
Quick Reference
grep -n "var .* = .*\^" *.mojo | head -20
grep -n "List\[.*\]()" *.mojo | grep -A 2 "\..*\["
grep -n "owned\|var.*=" *.mojo | sort
grep -n "DTypePointer\|alloc\|free\|__del__" *.mojo
grep -n "{" *.mojo | wc -l
Memory Safety Patterns
Safe Ownership Transfer:
- ✅
fn take(var data: List[Int]) - Caller loses access
- ✅
return self.data^ - Transfer from struct field
- ✅
var copy = data^ - Move to new variable
- ❌
fn take(data: List[Int]) - Ambiguous, use var
- ❌
return self.data - Missing transfer operator
Safe Initialization:
- ✅
var shape = List[Int]() then shape.append(dim)
- ✅
var data = DTypePointer[DType.float32].alloc(size)
- ✅ Check
size > 0 before allocation
- ❌
var list = List[Int]() then list[0] = value (uninitialized)
- ❌
alloc(0) or alloc(negative) (invalid size)
Safe Pointer Usage:
- ✅ Allocate before use:
alloc(size)
- ✅ Store size separately for bounds checking
- ✅ Verify pointer validity before dereference
- ❌ Use after free (manually deleted pointer)
- ❌ Out-of-bounds access
- ❌ Null pointer dereference
Safe Scope Management:
- ✅ Owned values dropped at scope end
- ✅ RAII pattern with proper cleanup
- ✅ Lifetime boundaries clear
- ❌ Variable used after scope exit
- ❌ Reference to stack variable returned
- ❌ Missing ownership transfer between scopes
Safety Validation Workflow
- Identify pointers: Find all pointer operations
- Check allocation: Verify all pointers allocated before use
- Trace ownership: Follow ownership transfers
- Verify lifetimes: Check value scopes
- Find violations: Identify safety issues
- Suggest fixes: Provide safety corrections
- Verify fixes: Compile to confirm safety
Output Format
Report memory safety issues with:
- Issue Type - Use-after-free, double-free, uninitialized, bounds, etc.
- Location - File and line number
- Code Snippet - The problematic code
- Root Cause - Why it's unsafe
- Risk Level - Segfault, undefined behavior, or warning
- Fix - How to correct it safely
Common Safety Issues & Fixes
Uninitialized List Access:
- Problem:
var list = List[Int](); list[0] = 5
- Risk: Out-of-bounds write, segmentation fault
- Fix: Use
list.append(5) instead
Use After Move:
- Problem:
var a = list^; print(list) (list moved, now invalid)
- Risk: Use-after-free
- Fix: Don't use list after transfer, or create copy
Missing Bounds Check:
- Problem: Access
tensor._data[index] without size check
- Risk: Out-of-bounds access, segfault
- Fix: Add
assert index < size or check in loop
Pointer Without Size:
- Problem:
var ptr = alloc(size) but size not tracked
- Risk: Invalid access, use-after-free
- Fix: Store size, verify before access
Double-Free:
- Problem: Manual
free() called twice on same pointer
- Risk: Heap corruption, segfault
- Fix: Use RAII, don't call free manually
Error Handling
| Problem | Solution |
|---|
| Compiler not available | Build with mojo build to get errors |
| Complex ownership | Trace step-by-step through ownership chain |
| Generic code | Check all type instantiations |
| External code | Verify contract assumptions |
| False positives | Verify with test execution |
Safety Checklist
Before committing Mojo code:
References
- See CLAUDE.md for ownership patterns
- See validate-mojo-patterns for pattern checking
- See mojo-lint-syntax for syntax issues