@@ -204,6 +204,30 @@ void test_mixed_sizes()
204204 }
205205}
206206
207+ void test_stack_remaining_bytes ()
208+ {
209+ printf (" test_stack_remaining_bytes\n " );
210+ // Verify that remaining_bytes returns a large value for non-heap
211+ // addresses (stack, globals). The sizeclass sentinel (raw value 0)
212+ // must have slab_mask = SIZE_MAX so that bounds checks pass for
213+ // non-snmalloc memory. Without the sentinel fix, remaining_bytes
214+ // would return 0, causing false-positive bounds check failures.
215+ char stack_buf[64 ];
216+ auto remaining = snmalloc::remaining_bytes<snmalloc::Config>(
217+ snmalloc::address_cast (stack_buf));
218+ EXPECT (
219+ remaining > sizeof (stack_buf),
220+ " remaining_bytes on stack address returned {}, expected large value" ,
221+ remaining);
222+
223+ // Also check that alloc_size returns 0 for stack addresses.
224+ auto sc = snmalloc::Config::Backend::template get_metaentry<true >(
225+ snmalloc::address_cast (stack_buf))
226+ .get_sizeclass ();
227+ auto sz = snmalloc::sizeclass_full_to_size (sc);
228+ EXPECT (sz == 0 , " alloc_size on stack address returned {}, expected 0" , sz);
229+ }
230+
207231int main ()
208232{
209233 printf (" large_nonpow2: non-power-of-2 large allocation tests\n " );
@@ -213,6 +237,7 @@ int main()
213237 test_many_allocations ();
214238 test_alloc_free_cycles ();
215239 test_mixed_sizes ();
240+ test_stack_remaining_bytes ();
216241
217242 printf (" large_nonpow2: all tests passed\n " );
218243 return 0 ;
0 commit comments