https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106635
Richard Earnshaw <rearnsha at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Resolution|--- |INVALID
Status|WAITING |RESOLVED
--- Comment #5 from Richard Earnshaw <rearnsha at gcc dot gnu.org> ---
Your original code contains (after stripping out the volatile):
u32 temp_32 = (u32)status_data_base_addr;
*dst++ = temp_32;
data_length++;
if(sizeof(addr_t) == 8) {
*dst++ = (u32)(((u64)status_data_base_addr)>>32);
data_length++;
}
Which of course on a 64-bit machine simplifies to
u32 temp_32 = (u32)status_data_base_addr;
*dst++ = temp_32;
data_length++;
*dst++ = (u32)(((u64)status_data_base_addr)>>32);
data_length++;
And which the compiler then further simplifies to
*([unaligned]u64*)dst = status_data_base_addr;
data_length += 2;
dst += 2;
If the location that dst points to is in normal, cachable, memory, then this
will be fine. But if you're writing to non-cachable memory, then you might get
a trap.
the correct fix is to mark dst as volatile in this case.
void CWLCollectReadRegData(volatile u32* dst,u16 reg_start, u32 reg_length,u32*
total_length, addr_t status_data_base_addr)