https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112447
--- Comment #14 from JuzheZhong <juzhe.zhong at rivai dot ai> --- Let me give you some guide which helps you to dig into the problem. First, reduce the case as follows: #include <string.h> void abort (void); void exit (int); #ifndef MAX_OFFSET #define MAX_OFFSET (sizeof (long long)) #endif #ifndef MAX_COPY #define MAX_COPY 15 #endif #ifndef MAX_EXTRA #define MAX_EXTRA (sizeof (long long)) #endif #define MAX_LENGTH (MAX_OFFSET + MAX_COPY + MAX_EXTRA) static union { char buf[MAX_LENGTH]; long long align_int; long double align_fp; } u; char A = 'A'; void reset () { int i; for (i = 0; i < MAX_LENGTH; i++) u.buf[i] = 'a'; } void check (int off, int len, int ch) { char *q; int i; q = u.buf; for (i = 0; i < off; i++, q++) if (*q != 'a') abort (); for (i = 0; i < len; i++, q++) if (*q != ch) abort (); for (i = 0; i < MAX_EXTRA; i++, q++) if (*q != 'a') abort (); } int main () { int len; char *p; /* off == 0 */ for (len = 0; len < MAX_COPY; len++) { reset (); p = memset (u.buf, '\0', len); if (p != u.buf) abort (); check (0, len, '\0'); p = memset (u.buf, A, len); if (p != u.buf) abort (); check (0, len, 'A'); p = memset (u.buf, 'B', len); if (p != u.buf) abort (); check (0, len, 'B'); } /* off == 1 */ for (len = 0; len < MAX_COPY; len++) { reset (); p = memset (u.buf+1, '\0', len); if (p != u.buf+1) abort (); check (1, len, '\0'); p = memset (u.buf+1, A, len); if (p != u.buf+1) abort (); check (1, len, 'A'); p = memset (u.buf+1, 'B', len); if (p != u.buf+1) abort (); check (1, len, 'B'); } exit (0); }