This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Non-word-aligned union assignment or read results in data abort

I am using the TI ARM compiler v5.0.4, with the TMS570 microcontroller. I've encountered a compiler bug when assigning unions. Attached is a program with different tests.

Assignments to unions are implemented using the STMEA instruction and reading unions using the LDMFD instruction. When the union is not word-aligned, this leads to data abort exceptions. See the example program, test cases 1 and 2.

As a workaround, one can use the memcpy method, though that is optimized to STMEA and LDMFD instructions when passed union pointers or void pointers. To force a call to memcpy, one can cast  the source to a uint8_t*. See test case 3.

This is not a problem for structs, as there the assignment seem to always be translated to a memcpy call. See test case 4.

When embedding a union in a struct the generated code behave correctly, as the union is word-aligned in the struct. When packing the struct, memcpy is used to copy the data (also correct). See test case 5.

  • So, lets add my questions:

    • Is my assessment that these are compiler bugs correct, or am I missing something?
    • Are there other workarounds available apart from using memcpy?
    • What is the expected release time for a fix?

    Regards,

    Hugo

  • The problem can be reduced to non-word aligned struct accesses.

    I've attached a very small example that triggers the error.

  • I'm surprised that Archaeologist or George Mock hasn't chimed in yet. I think what you are seeing is by design and to spec. I think the compiler expects structures to be allocated via declaration. The compiler will ensure that the declared structure is aligned properly. With structure to structure copy, the compiler assumes correct alignment and uses the most efficient aligned copy instructions. It's only when either destination or source is known to unaligned that the compiler will result to a byte by byte copy. Giving a structure the unpacked attribute would tag a structure as unaligned. As part of it's optimization, it looks like the compiler also replaces memcpy calls with inlined aligned copies. What are trying to do? Are you unpacking a packed structure into a unpacked structure?

  • Norman Wong said:
    I'm surprised that Archaeologist or George Mock hasn't chimed in yet.

    We've got to give everyone else a chance to respond once in a while.

    Norman is correct, example_simple.c invokes undefined behavior by casting an address that is not properly aligned for type "struct S" into the type pointer to "struct S".  This program is not a legal C program.  The remedy here is as suggested, use "unpacked".

  • You're right: according to ISO C99 (§6.3.2.3): "A pointer to an object type may be converted to a pointer to a different object type. If the resulting pointer is not correctly aligned for the referenced type, the behavior is undefined."

    I was trying to save memory by packing structures containing other structures, and then passing pointers of the inner structures to other methods. I'll align the structures, and see if I can reorder the fields to save space.

    I assume this means that you should never pass pointers to objects in a packed structure, as the information that the object is unaligned is lost in the method call.

    Thanks for the anser!

    Hugo