Opened 12 months 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;
}

Attachments (1)

size_align_32_fail.cfa (1.4 KB) - added by caparson 12 months ago.
Copy of the bug reproduction

Download all attachments as: .zip

Change History (1)

Changed 12 months ago by caparson

Attachment: size_align_32_fail.cfa added

Copy of the bug reproduction

Note: See TracTickets for help on using tickets.