https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93249
Martin Sebor <msebor at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|UNCONFIRMED |NEW Last reconfirmed| |2020-01-13 CC| |msebor at gcc dot gnu.org Summary|[10 Regression] wrong code |[10 Regression] wrong code |with __builtin_strncpy() at |with __builtin_strncpy() |-O1 |copying empty string Ever confirmed|0 |1 --- Comment #1 from Martin Sebor <msebor at gcc dot gnu.org> --- Confirmed. The DSE pass transforms the first strncpy call as shown in the dump below. Since the second element of the source string d is non-zero it writes its value into the destination at b[3], rather that storing two nuls there as the original code does. I can reproduce it at all optimization levels and with -fno-optimize-strlen. $ gcc -O -S -Wall -fdump-tree-dse1-details=/dev/stdout pr93249.c ;; Function main (main, funcdef_no=0, decl_uid=1932, cgraph_uid=1, symbol_order=2) Trimming statement (head = 1, tail = 0): __builtin_strncpy (&b[2], &d, 2); main () { char d[2]; char _1; char _2; char _3; char _4; <bb 2> : d = "\x00\x11"; __builtin_strncpy (&MEM <char> [(void *)&b + 3B], &MEM <char> [(void *)&d + 1B], 1); __builtin_strncpy (&b[1], &a, 2);