Skip to content

Commit 36c1a84

Browse files
committed
fix windows compilation with c_alloc
1 parent fc1329a commit 36c1a84

File tree

7 files changed

+46
-23
lines changed

7 files changed

+46
-23
lines changed

.github/workflows/test.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,12 @@ jobs:
4343

4444
- name: Run all tests
4545
if: steps.install_rust.outcome == 'success'
46+
continue-on-error: false
4647
run: cargo +${{ matrix.rust }} test --verbose --features ${{ matrix.features }}
4748

4849
- name: Run Miri
4950
if: matrix.rust == 'nightly' && steps.install_rust.outcome == 'success'
51+
continue-on-error: false
5052
env:
5153
MIRIFLAGS: -Zmiri-permissive-provenance
5254
run: cargo +${{ matrix.rust }} miri test --verbose --features ${{ matrix.features }}

CHANGELOG.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1111

1212
---
1313

14-
## [0.11.3]
14+
## [0.11.3] - 2026-02-15
15+
16+
### Fixed
17+
18+
* Crate failing to compile on Windows with the `c_alloc` feature
19+
20+
## [0.11.3] - 2026-02-15
1521

1622
### Fixed
1723

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "memapi2"
3-
version = "0.11.3"
3+
version = "0.11.4"
44
edition = "2018"
55
rust-version = "1.46.0"
66
authors = ["echohumm"]

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
A small, `no_std`/`no_alloc`-friendly allocation interface for raw buffers, with explicit layouts,
77
split allocator traits, and structured errors.
88

9-
Version: 0.11.3
9+
Version: 0.11.4
1010
MSRV: 1.46.0 (some features require newer compilers or nightly; see [Feature flags](#feature-flags))
1111

1212
## Highlights
@@ -31,14 +31,14 @@ MSRV: 1.46.0 (some features require newer compilers or nightly; see [Feature fla
3131

3232
```toml
3333
[dependencies]
34-
memapi2 = "0.11.3"
34+
memapi2 = "0.11.4"
3535
```
3636

3737
If you want common optional features:
3838

3939
```toml
4040
[dependencies]
41-
memapi2 = { version = "0.11.3", features = ["os_err_reporting"] }
41+
memapi2 = { version = "0.11.4", features = ["os_err_reporting"] }
4242
```
4343

4444
## Example

src/allocs/c_alloc.rs

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
use {
22
crate::{
33
error::{Cause, Error},
4-
ffi::c_alloc::{c_alloc, c_dealloc, c_zalloc, grow_aligned, shrink_aligned}
5-
,
4+
ffi::c_alloc::{c_alloc, c_dealloc, c_zalloc, grow_aligned, shrink_aligned},
65
layout::Layout,
76
traits::{
8-
alloc::{Alloc, Dealloc, Grow, Realloc, Shrink},
9-
AllocError
7+
AllocError,
8+
alloc::{Alloc, Dealloc, Grow, Realloc, Shrink}
109
}
1110
},
1211
::core::{
@@ -106,7 +105,9 @@ unsafe fn pad_then_realloc(
106105
match old_size.cmp(&new_padded.size()) {
107106
// SAFETY: caller guarantees that `old_ptr` and `old_size` are valid, we just
108107
// checked that `size >= old_size`
109-
Ordering::Less => unsafe { grow_aligned(old_ptr, old_align, old_size, align, size, zeroed) },
108+
Ordering::Less => unsafe {
109+
grow_aligned(old_ptr, old_align, old_size, align, size, zeroed)
110+
},
110111
Ordering::Equal => {
111112
if align > old_align {
112113
// SAFETY: above
@@ -117,7 +118,9 @@ unsafe fn pad_then_realloc(
117118
}
118119
// SAFETY: caller guarantees that `old_ptr` and `size` are valid, we just checked
119120
// that `size <= old_size`
120-
Ordering::Greater => unsafe { shrink_aligned(old_ptr, old_align, align, size) }
121+
Ordering::Greater => unsafe {
122+
shrink_aligned(old_ptr, old_align, old_size, align, size)
123+
}
121124
}
122125
})
123126
}
@@ -157,7 +160,7 @@ impl Dealloc for CAlloc {
157160
Err(Error::DanglingDeallocation)
158161
} else {
159162
let padded = tri!(do layout.to_posix_memalign_compatible());
160-
c_dealloc(ptr.as_ptr().cast(), padded.align());
163+
c_dealloc(ptr.as_ptr().cast(), padded.align(), padded.size());
161164
Ok(())
162165
}
163166
}
@@ -196,7 +199,13 @@ impl Shrink for CAlloc {
196199
let new_padded = tri!(do new_layout.to_posix_memalign_compatible());
197200

198201
null_q_dyn_zsl_check_or_errcode(new_layout, |_| {
199-
shrink_aligned(ptr.as_ptr().cast(), old_padded.align(), new_padded.align(), new_padded.size())
202+
shrink_aligned(
203+
ptr.as_ptr().cast(),
204+
old_padded.align(),
205+
old_padded.size(),
206+
new_padded.align(),
207+
new_padded.size()
208+
)
200209
})
201210
}
202211
}

src/ffi/c_alloc.rs

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -130,17 +130,23 @@ const NULL: *mut c_void = null_mut();
130130
///
131131
/// - `old_ptr` must point to a C allocation of at least `size` bytes.
132132
/// - `ptr` must point to an allocation of at least `size` bytes.
133-
pub unsafe fn try_move(ptr: *mut c_void, old_ptr: *mut c_void, size: usize, old_align: usize) {
133+
pub unsafe fn try_move(
134+
ptr: *mut c_void,
135+
old_ptr: *mut c_void,
136+
copy_count: usize,
137+
old_align: usize,
138+
old_size: usize
139+
) {
134140
if ptr != NULL {
135141
// SAFETY: `ptr` validated nonnull, caller guarantees `old_ptr` is valid. caller guarantees
136142
// `size` is <= size of allocation at `ptr` and <= size of allocation at `old_ptr`,
137143
// so copying that many bytes is safe.
138144
unsafe {
139-
memcpy(ptr, old_ptr, size);
145+
memcpy(ptr, old_ptr, copy_count);
140146
}
141147
// SAFETY: caller guarantees that `old_ptr` is valid
142148
unsafe {
143-
c_dealloc(old_ptr, old_align);
149+
c_dealloc(old_ptr, old_align, old_size);
144150
}
145151
}
146152
}
@@ -249,11 +255,11 @@ pub unsafe fn c_zalloc(align: usize, size: usize) -> (*mut c_void, c_int) {
249255
/// - `ptr` points to the start of a valid allocation returned by an allocation function listed
250256
/// above, or is `NULL`.
251257
/// - `ptr` has not yet been deallocated.
252-
pub unsafe fn c_dealloc(ptr: *mut c_void, _align: usize) {
258+
pub unsafe fn c_dealloc(ptr: *mut c_void, _size: usize, _align: usize) {
253259
#[cfg(windows)]
254260
{
255261
#[allow(clippy::used_underscore_binding)]
256-
if _align > MIN_ALIGN && size >= align {
262+
if _align > MIN_ALIGN && _size >= _align {
257263
// SAFETY: requirements are passed onto the caller; as align > MIN_ALIGN,
258264
// _aligned_{malloc,realloc} was used so _aligned_free works.
259265
unsafe {
@@ -316,7 +322,7 @@ pub unsafe fn grow_aligned(
316322
// if successful, move data to new pointer
317323
// SAFETY: requirements are passed on to the caller
318324
unsafe {
319-
try_move(ptr, old_ptr, old_size, old_align);
325+
try_move(ptr, old_ptr, old_size, old_align, old_size);
320326
}
321327

322328
(ptr, status)
@@ -346,6 +352,7 @@ pub unsafe fn grow_aligned(
346352
pub unsafe fn shrink_aligned(
347353
old_ptr: *mut c_void,
348354
old_align: usize,
355+
old_size: usize,
349356
align: usize,
350357
size: usize // a zero here is useless, as it will just be overwritten anyway.
351358
) -> (*mut c_void, c_int) {
@@ -357,7 +364,7 @@ pub unsafe fn shrink_aligned(
357364
// if successful, move data to new pointer
358365
// SAFETY: requirements are passed on to the caller
359366
unsafe {
360-
try_move(ptr, old_ptr, size, old_align);
367+
try_move(ptr, old_ptr, size, old_align, old_size);
361368
}
362369

363370
(ptr, status)
@@ -426,7 +433,6 @@ extern "C" {
426433
will leak memory"]
427434
pub fn aligned_alloc(align: usize, size: usize) -> *mut c_void;
428435

429-
#[cfg(not(windows))]
430436
/// Frees memory previously returned by the primary C allocator.
431437
///
432438
/// The closest Rust equivalent is [`dealloc`](::stdalloc::alloc::dealloc).

src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,8 @@
8888

8989
extern crate core;
9090
extern crate rustversion;
91-
#[cfg(feature = "c_alloc")]
92-
extern crate cty;
91+
92+
#[cfg(feature = "c_alloc")] extern crate cty;
9393

9494
#[cfg(not(feature = "no_alloc"))] extern crate alloc as stdalloc;
9595
#[cfg(all(feature = "std", feature = "no_alloc"))] extern crate std as stdalloc;

0 commit comments

Comments
 (0)