https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111849
Bug ID: 111849 Summary: GCC replaces volatile struct assignments with memcpy calls Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: target Assignee: unassigned at gcc dot gnu.org Reporter: bugdal at aerifal dot cx Target Milestone: --- On at least some targets where GCC compiles struct assignments to memcpy calls, this pattern is also used when the struct objects involved are volatile-qualified. This is invalid; the memcpy function has no contract to work on volatile objects, and making it compatible with volatile objects would impose extreme implementation constraints that would limit its performance. For example, memcpy may copy the same byte more than once to avoid branches, may use special store instructions with particular cache semantics or data transfer sizes that aren't compatible with various volatile objects like memory-mapped registers, etc. I don't think the C standard is very clear on what is supposed to happen for volatile struct assignments, but they should at least be done in a way that's known to be compatible with any memory-mapped interfaces supported on the target architecture, and the safe behavior is probably implementing them as member-by-member assignment with some fixup for padding. I found this while looking at ways to suppress generation of external calls to memcpy when compiling very restrictive TUs that aren't allowed to make any external calls, and being surprised that "just add volatile" was not one of the ways. I'm filing this as target component because I think the transformation is taking place at the target backend layer on affected targets rather than earlier, but I'm not certain. This should be reviewed and possibly reclassified if that's wrong.