Skip to content

Commit

Permalink
fix undefined behavior in SetU32 same as with SetU64 before
Browse files Browse the repository at this point in the history
  • Loading branch information
droundy committed Feb 6, 2022
1 parent 3b52ff2 commit cf91335
Showing 1 changed file with 34 additions and 26 deletions.
60 changes: 34 additions & 26 deletions src/setu32.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,16 @@ impl_set_methods!(SetU32);
#[repr(C)]
#[derive(Debug)]
struct S {
b: Sbeginning,
array: u32,
}

#[repr(C)]
#[derive(Debug)]
struct Sbeginning {
sz: u32,
cap: u32,
bits: u32,
array: u32,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
Expand Down Expand Up @@ -321,7 +327,7 @@ enum Internal<'a> {
/// significant bits) giving the elements in the set, and in the most
/// significant bits a value representing the offset of the bitmap.
Heap {
s: &'a S,
s: &'a Sbeginning,
a: &'a [u32],
},
/// This is for the case where the maximum number in our set is so large
Expand All @@ -332,7 +338,7 @@ enum Internal<'a> {
/// unique value (which we change if that unique value gets added to the
/// set).
Big {
s: &'a S,
s: &'a Sbeginning,
a: &'a [u32],
},
// The data is stored as a bitmap. This is used when the number of elements
Expand All @@ -346,11 +352,11 @@ enum InternalMut<'a> {
Empty,
Stack(Tiny),
Heap {
s: &'a mut S,
s: &'a mut Sbeginning,
a: &'a mut [u32],
},
Big {
s: &'a mut S,
s: &'a mut Sbeginning,
a: &'a mut [u32],
},
Dense {
Expand Down Expand Up @@ -740,8 +746,8 @@ impl SetU32 {
if ptr == std::ptr::null_mut() {
std::alloc::handle_alloc_error(layout_for_capacity(c));
}
(*ptr).cap = (*other.0).cap;
(*ptr).bits = (*other.0).bits;
(*ptr).b.cap = (*other.0).b.cap;
(*ptr).b.bits = (*other.0).b.bits;
SetU32(ptr)
}
} else {
Expand Down Expand Up @@ -836,15 +842,15 @@ impl SetU32 {
let ptr = self.0;
let cap = 1 + mx/32 + mx/128;

let oldcap = (*ptr).cap;
let oldcap = (*ptr).b.cap;
self.0 = std::alloc::realloc(ptr as *mut u8,
layout_for_capacity(oldcap as usize),
bytes_for_capacity(cap as usize)) as *mut S;
if self.0 as usize == 0 {
std::alloc::handle_alloc_error(layout_for_capacity(cap as usize));
}
(*self.0).cap = cap;
(*self.0).sz += 1;
(*self.0).b.cap = cap;
(*self.0).b.sz += 1;
match self.internal_mut() {
InternalMut::Dense { a, .. } => {
for i in oldcap as usize .. a.len() {
Expand All @@ -861,8 +867,8 @@ impl SetU32 {
// This should be stored in a dense bitset.
unsafe {
let x = SetU32(std::alloc::alloc_zeroed(layout_for_capacity(cap as usize)) as *mut S);
(*x.0).cap = cap;
(*x.0).bits = 32;
(*x.0).b.cap = cap;
(*x.0).b.bits = 32;
x
}
}
Expand All @@ -880,8 +886,8 @@ impl SetU32 {
if cap > 0 {
unsafe {
let x = SetU32(std::alloc::alloc_zeroed(layout_for_capacity(cap)) as *mut S);
(*x.0).cap = cap as u32;
(*x.0).bits = if bits == 0 {
(*x.0).b.cap = cap as u32;
(*x.0).b.bits = if bits == 0 {
let mut b = 0;
while b <= 32 {
b = crate::rand::rand32();
Expand Down Expand Up @@ -1259,13 +1265,14 @@ impl SetU32 {
Internal::Stack(Tiny::from_usize(self.0 as usize))
} else {
let s = unsafe { &*self.0 };
let a = unsafe { std::slice::from_raw_parts(&s.array as *const u32, s.cap as usize) };
if s.bits == 0 || s.bits > 32 {
Internal::Big { s, a }
} else if s.bits == 32 {
Internal::Dense { sz: s.sz, a }
let b = &s.b;
let a = unsafe { std::slice::from_raw_parts(&s.array as *const u32, b.cap as usize) };
if b.bits == 0 || b.bits > 32 {
Internal::Big { s: b, a }
} else if b.bits == 32 {
Internal::Dense { sz: b.sz, a }
} else {
Internal::Heap { s, a }
Internal::Heap { s: b, a }
}
}
}
Expand All @@ -1277,13 +1284,14 @@ impl SetU32 {
InternalMut::Stack(Tiny::from_usize(self.0 as usize))
} else {
let s = unsafe { &mut *self.0 };
let a = unsafe { std::slice::from_raw_parts_mut(&mut s.array as *mut u32, s.cap as usize) };
if s.bits == 0 || s.bits > 32 {
InternalMut::Big { s, a }
} else if s.bits == 32 {
InternalMut::Dense { sz: &mut s.sz, a }
let b = &mut s.b;
let a = unsafe { std::slice::from_raw_parts_mut(&mut s.array as *mut u32, b.cap as usize) };
if b.bits == 0 || b.bits > 32 {
InternalMut::Big { s: b, a }
} else if b.bits == 32 {
InternalMut::Dense { sz: &mut b.sz, a }
} else {
InternalMut::Heap { s, a }
InternalMut::Heap { s: b, a }
}
}
}
Expand Down

0 comments on commit cf91335

Please sign in to comment.