3232#include " tcmalloc/internal/memory_tag.h"
3333#include " tcmalloc/internal_malloc_extension.h"
3434#include " tcmalloc/malloc_extension.h"
35+ #include " tcmalloc/static_vars.h"
3536#include " tcmalloc/tcmalloc.h"
37+ #include " tcmalloc/tcmalloc_policy.h"
3638#include " tcmalloc/testing/testutil.h"
3739
3840namespace tcmalloc ::tcmalloc_internal {
@@ -167,10 +169,51 @@ void MismatchedAlignedDelete(
167169 } else {
168170 ptr = TCMallocInternalNewNothrow (size, std::nothrow);
169171 }
172+
170173 if (ptr == nullptr ) {
171174 return ;
172175 }
173176
177+ // Alignment mismatches that result in different size classes
178+ // will cause catatrophic failures. Detection of such error
179+ // conditions is tested, but we need to by-pass inputs that are
180+ // valid.
181+ //
182+ // Here are the normal conditions to be bypassed:
183+ // 1. Alignment is specified neither in allocation nor deallocation
184+ // -- always ok
185+ // 2. Alignment is specified in allocation, but not deallocation:
186+ // -- ok when the size of the corresponding size class's
187+ // -- natural alignment >= requested alignment (then no size class
188+ // -- adjustment is needed in deallocation)
189+ // 3. Alignment is not specified in allocation, but in deallocation
190+ // -- same as above
191+ // 4. When both are specified:
192+ // -- ok when the alignment are equal or
193+ // -- both are greater than kPageSize or
194+ // -- size_class adjustments are needed in neither cases.
195+
196+ auto [is_small_a, size_class_a] =
197+ allocated_alignment.has_value ()
198+ ? tc_globals.sizemap ().GetSizeClass (
199+ CppPolicy ().Nothrow ().AlignAs (*allocated_alignment), size)
200+ : tc_globals.sizemap ().GetSizeClass (CppPolicy ().Nothrow (), size);
201+
202+ auto [is_small_d, size_class_d] =
203+ deallocated_alignment.has_value ()
204+ ? tc_globals.sizemap ().GetSizeClass (
205+ CppPolicy ().Nothrow ().AlignAs (*deallocated_alignment), size)
206+ : tc_globals.sizemap ().GetSizeClass (CppPolicy ().Nothrow (), size);
207+
208+ if (is_small_a && is_small_d && size_class_a == size_class_d) {
209+ if (deallocated_alignment.has_value ()) {
210+ TCMallocInternalDeleteSizedAligned (ptr, size, *deallocated_alignment);
211+ } else {
212+ TCMallocInternalDeleteSized (ptr, size);
213+ }
214+ return ;
215+ }
216+
174217 LongJmpScope scope;
175218 if (setjmp (scope.buf_ )) {
176219 return ;
@@ -181,7 +224,11 @@ void MismatchedAlignedDelete(
181224 } else {
182225 TCMallocInternalDeleteSized (ptr, size);
183226 }
184- EXPECT_EQ (allocated_alignment, deallocated_alignment);
227+
228+ // The alignment error detecion is only available with debug build
229+ #ifndef NDEBUG
230+ EXPECT_TRUE (!is_small_a && !is_small_d);
231+ #endif
185232}
186233
187234FUZZ_TEST (MemoryErrorsFuzzTest, MismatchedAlignedDelete)
0 commit comments