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)

Reply via email to