Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Release notes

## Version [v0.2.2] - 2026.02.03

### Fixed

* Revert changes in `@buffer` macro that introduced scope issues (i.e., let and try blocks).

## Version [v0.2.1] - 2026.02.03

### Fixed
Expand Down
27 changes: 11 additions & 16 deletions src/mbuffer.jl
Original file line number Diff line number Diff line change
Expand Up @@ -130,13 +130,10 @@ end
macro buffer(specs, ex)
buf, T, len = _parse_specs(specs)
quote
let $(esc(buf)) = MAllocBuffer{$(esc(T))}($(esc(len)))
try
$(esc(ex))
finally
free!($(esc(buf)))
end
end
$(esc(buf)) = MAllocBuffer{$(esc(T))}($(esc(len)))
$(esc(ex))
free!($(esc(buf)))
$(esc(buf)) = nothing
Comment on lines +133 to +136

Copilot AI Feb 3, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removing the let/try...finally structure here means free! is no longer guaranteed to run if ex throws, so MAllocBuffer's underlying memory will leak on exceptions (there is no finalizer on MAllocBuffer, and free! is the only place that calls Libc.free). Please restore exception-safe cleanup (e.g., via a try...finally or equivalent pattern that still fixes the scope issue) so that @buffer truly frees the buffer after use even on error.

Copilot uses AI. Check for mistakes.
end
end

Expand All @@ -150,15 +147,13 @@ macro buffer(specs, specs2, ex)
buf, T, len = _parse_specs(specs)
buf2, T2, len2 = _parse_specs(specs2)
quote
let $(esc(buf)) = MAllocBuffer{$(esc(T))}($(esc(len))),
$(esc(buf2)) = MAllocBuffer{$(esc(T2))}($(esc(len2)))
try
$(esc(ex))
finally
free!($(esc(buf2)))
free!($(esc(buf)))
end
end
$(esc(buf)) = MAllocBuffer{$(esc(T))}($(esc(len)))
$(esc(buf2)) = MAllocBuffer{$(esc(T2))}($(esc(len2)))
$(esc(ex))
free!($(esc(buf2)))
free!($(esc(buf)))
$(esc(buf2)) = nothing
$(esc(buf)) = nothing
Comment on lines +150 to +156

Copilot AI Feb 3, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As with the single-buffer macro, dropping the let/try...finally wrapper means that if ex throws, neither free!($(esc(buf2))) nor free!($(esc(buf))) will run, leaking both MAllocBuffer instances. Consider reinstating an exception-safe cleanup pattern that still avoids the scope issues you observed, so both buffers are always freed even when ex fails.

Copilot uses AI. Check for mistakes.
end
end

Expand Down
Loading