Issue |
140241
|
Summary |
cursor.extent or clang_getCursorExtent() crashes on TRANSLATION_UNIT cursor on macOS, but works on Linux
|
Labels |
new issue
|
Assignees |
|
Reporter |
zokrezyl
|
# Title:
`clang_getCursorExtent()` crashes on TRANSLATION_UNIT cursor on macOS but works on Linux
## Description:
When calling `clang_getCursorExtent()` on a `CursorKind.TRANSLATION_UNIT` cursor, and then accessing `.start` or `.end` of the resulting `CXSourceRange`, a **segmentation fault occurs on macOS**.
This happens **consistently across**:
- **Python versions**: 3.11, 3.12, 3.13, and 3.14
- **Clang versions**: 18.x.y and 19.x.y (built from Homebrew or official sources)
- **macOS versions**: (tested on macOS 14.4+ Apple Silicon and Intel)
## Reproducer (Python `clang.cindex` bindings):
```python
from clang import cindex
cindex.Config.set_library_file("/opt/homebrew/opt/llvm/lib/libclang.dylib") # adjust if needed
index = cindex.Index.create()
tu = index.parse("example.cpp", args=["-std=c++17"]) # file contains `int main() { return 0; }`
cursor = tu.cursor # this is of kind TRANSLATION_UNIT
# These work:
print(cursor.kind)
print(cursor.spelling)
print(cursor.location)
# This also works (struct is returned)
print(cursor.extent.ptr_data)
print(cursor.extent.begin_int_data)
print(cursor.extent.end_int_data)
# But this crashes:
print(cursor.extent.start) # or `.end` → causes a segmentation fault on macOS
```
On Linux, this behaves safely — `extent.start.file` may be `None`, but no crash occurs.
## C-level Reproducer:
```c
CXIndex index = clang_createIndex(0, 0);
CXTranslationUnit tu = clang_parseTranslationUnit(index, "example.cpp", NULL, 0, NULL, 0, CXTranslationUnit_None);
CXCursor cursor = clang_getTranslationUnitCursor(tu);
CXSourceRange range = clang_getCursorExtent(cursor);
CXSourceLocation start = clang_getRangeStart(range); // 💥 Segfaults on macOS
```
## Expected Behavior
`clang_getCursorExtent()` should never return a `CXSourceRange` that causes `clang_getRangeStart()` or `clang_getRangeEnd()` to crash, even for synthetic cursors like `TRANSLATION_UNIT`.
If no valid extent exists, it should:
- return a dummy or sentinel range, or
- document that `.extent` is unsafe to access on certain kinds (not currently documented in `libclang`)
## Notes
- This crash does not occur when calling `.extent.start` on normal entities like functions, structs, typedefs, etc.
- The bug only affects the `TRANSLATION_UNIT` cursor, which is returned by `clang_getTranslationUnitCursor()`.
- The Python `clang.cindex` binding merely exposes the crash; the underlying issue is in `clang_getRangeStart()` accessing bad memory.
## Suggested Fix
Either:
- Have `clang_getCursorExtent()` return a well-defined dummy `CXSourceRange` for `TRANSLATION_UNIT`, or
- Have `clang_getRangeStart()` gracefully reject invalid or synthetic ranges, or
- Document that `TRANSLATION_UNIT` has no valid range
_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs