Skip to content

Commit 251313d

Browse files
committed
refactor: experimental migration to memcpy for strict-aliasing compliance
- Replace raw pointer casting in metadata read/write functions with standard-compliant memcpy. - Tighten static analysis by hardening warning flags to `-Wstrict-aliasing=1`.
1 parent e4f64e2 commit 251313d

2 files changed

Lines changed: 17 additions & 8 deletions

File tree

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ BASE_CFLAGS = -Werror -Wall -Wextra \
2828
-Wshadow \
2929
-Wconversion -Wsign-conversion \
3030
-Wundef \
31-
-Wstrict-aliasing=2 \
31+
-Wstrict-aliasing=1 \
3232
-Wpointer-arith \
3333
-Wdouble-promotion \
3434
-Wcast-align \

easy_stack.h

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -772,25 +772,31 @@ static inline size_t estack_read_meta(const EStack *stack, size_t meta_type, siz
772772

773773
// Case 1 (< 64 KB): Highly likely scenario for thread-local/scratchpad workloads
774774
if (ESTACK_LIKELY(meta_type == 1)) {
775-
return ((uint16_t *)(void *)end_of_stack_header)[index];
775+
uint16_t val;
776+
memcpy(&val, (const void *)(end_of_stack_header + (index * sizeof(uint16_t))), sizeof(uint16_t));
777+
return val;
776778
}
777779

778780
// Case 2 (< 4 GB): Highly likely scenario for large desktop/game-engine stacks
779781
#if UINTPTR_MAX >= 0xFFFFFFFFUL
780782
if (ESTACK_LIKELY(meta_type == 2)) {
781-
return ((uint32_t *)(void *)end_of_stack_header)[index];
783+
uint32_t val;
784+
memcpy(&val, (const void *)(end_of_stack_header + (index * sizeof(uint32_t))), sizeof(uint32_t));
785+
return val;
782786
}
783787
#endif
784788

785789
// Case 0 (< 256 B): Micro-allocations or small static buffers
786790
if (meta_type == 0) {
787-
return ((uint8_t *)(void *)end_of_stack_header)[index];
791+
return ((const uint8_t *)(const void *)end_of_stack_header)[index];
788792
}
789793

790794
// Case 3 (>= 4 GB): Highly unlikely for standard stack allocators
791795
#if UINTPTR_MAX == 0xFFFFFFFFFFFFFFFFULL
792796
if (ESTACK_UNLIKELY(meta_type == 3)) {
793-
return ((uint64_t *)(void *)end_of_stack_header)[index];
797+
uint64_t val;
798+
memcpy(&val, (const void *)(end_of_stack_header + (index * sizeof(uint64_t))), sizeof(uint64_t));
799+
return val;
794800
}
795801
#endif
796802

@@ -810,14 +816,16 @@ static inline void estack_write_meta(EStack *stack, size_t meta_type, size_t ind
810816

811817
// Case 1 (< 64 KB): Highly likely scenario for thread-local/scratchpad workloads
812818
if (ESTACK_LIKELY(meta_type == 1)) {
813-
((uint16_t *)(void *)end_of_stack_header)[index] = (uint16_t)value;
819+
uint16_t val16 = (uint16_t)value;
820+
memcpy((void *)(end_of_stack_header + index * sizeof(uint16_t)), &val16, sizeof(uint16_t));
814821
return;
815822
}
816823

817824
// Case 2 (< 4 GB): Highly likely scenario for large desktop/game-engine stacks
818825
#if UINTPTR_MAX >= 0xFFFFFFFFUL
819826
if (ESTACK_LIKELY(meta_type == 2)) {
820-
((uint32_t *)(void *)end_of_stack_header)[index] = (uint32_t)value;
827+
uint32_t val32 = (uint32_t)value;
828+
memcpy((void *)(end_of_stack_header + index * sizeof(uint32_t)), &val32, sizeof(uint32_t));
821829
return;
822830
}
823831
#endif
@@ -831,7 +839,8 @@ static inline void estack_write_meta(EStack *stack, size_t meta_type, size_t ind
831839
// Case 3 (>= 4 GB): Highly unlikely for standard stack allocators
832840
#if UINTPTR_MAX == 0xFFFFFFFFFFFFFFFFULL
833841
if (ESTACK_UNLIKELY(meta_type == 3)) {
834-
((uint64_t *)(void *)end_of_stack_header)[index] = (uint64_t)value;
842+
uint64_t val64 = (uint64_t)value;
843+
memcpy((void *)(end_of_stack_header + index * sizeof(uint64_t)), &val64, sizeof(uint64_t));
835844
return;
836845
}
837846
#endif

0 commit comments

Comments
 (0)