Opened 2 years ago
#274 new defect
Size of struct and alignment/offset of polymorphic fields inside a struct is incorrect on 32 bit
Reported by: | caparson | Owned by: | |
---|---|---|---|
Priority: | major | Component: | cfa-cc |
Version: | 1.0 | Keywords: | 32-bit, box, sizeof, alignof, alignment, offset, forall, polymorphic |
Cc: |
Description ¶
If a polymorphic field of a struct is not the first field the alignment of fields and the size of the struct on 32 bit may be wrong in certain cases. The generated alignment of field accesses seems to differ if the struct is passed by value or reference. Additionally, there may be some relation to fields being 4-byte aligned in some cases on 32-bit.
While this is not fixed, it can be avoided in any cases where you only have one polymorphic field in a struct by making the polymorphic field the first field in the struct.
Repro with some prints to highlight issues:
Code highlighting:
forall( T ) { struct chan_write { int a; T elem; }; static inline void ?{}( chan_write(T) & cw, T elem ) { printf("ctor\tsize of cw: %lu, size of a: %zu, size of elem: %lu\n", sizeof(cw), sizeof(cw.a), sizeof(cw.elem)); cw.elem = elem; printf("ctor\telem: %lld, elem ptr: %p, cw ptr: %p\n", *((long long int *)&cw.elem), &cw.elem, &cw); } static inline void print( chan_write(T) & cw ) { printf("PRINT\tsizeof cw: %lu, sizeof a: %zu, sizeof elem: %lu\n", sizeof(cw), sizeof(cw.a), sizeof(cw.elem)); printf("PRINT\telem: %lld, elem ptr: %p, cw ptr: %p\n", *((long long int *)&(cw.elem)), &cw.elem, &cw); } static inline void print_noref( chan_write(T) cw ) { printf("NoRef\tsizeof cw: %lu, size of a: %zu, sizeof elem: %lu\n", sizeof(cw), sizeof(cw.a), sizeof(cw.elem)); printf("NoRef\telem: %lld, elem ptr: %p, cw ptr: %p\n", *((long long int *)&(cw.elem)), &cw.elem, &cw); } } int main() { long long int INDEX = 1; printf("i: %lld, sizeof i: %zu\n", INDEX, sizeof(INDEX)); chan_write(long long int) apple{ INDEX }; printf("main\tsizeof cw: %zu, sizeof a: %zu, sizeof elem: %zu\n", sizeof(apple), sizeof(apple.a), sizeof(apple.elem)); printf("main\telem: %lld, elem ptr: %p, cw ptr: %p\n", apple.elem, &apple.elem, &apple); print( apple ); print_noref( apple ); return 0; }
Note: See
TracTickets for help on using
tickets.
Copy of the bug reproduction