https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94015
--- Comment #6 from Martin Sebor <msebor at gcc dot gnu.org> --- (In reply to Nate Eldredge from comment #4) A compile-time only test that doesn't depend on the target or endianness would be much better than a runtime test that fails only on a subset of targets. The way to do that is to verify that the pass doesn't misinterpret the size of the pointer stored in the array as the length of the string by checking to make sure that the result of a strlen call with the buffer as an argument isn't folded into a constant: /* PR tree-optimization/94015 - assignment incorrectly omitted by -foptimize-strlen { dg-do compile } { dg-options "-O2 -Wall -fdump-tree-optimized" } */ int f (int n) { char *s = __builtin_malloc (n); *(char **)s = "0123456"; return __builtin_strlen (s); } /* { dg-final { scan-tree-dump-times "strlen" 1 "optimized" } } */ The buggy count_nonzero_bytes function is tricky because it tries to recover string length information obscured by earlier optimizations like store merging that turn multiple character stores into one. The merged stores can have different forms, be of a variety of different types, and result in ranges of lengths (i.e., minimum and maximum). For instance this: char a[8]; void f (void) { char s[] = "1234567"; __builtin_memcpy (a, s, sizeof s); } is transformed into this: f (char * p) { <bb 2> [local count: 1073741824]: MEM <long unsigned int> [(char * {ref-all})&a] = 15540725856023089; return; } count_nonzero_bytes then goes and figures out the length of the string the number corresponds to. To detect buffer overflows, it also computes the size of the store, and when the store is one of a pointer type, it gets the size and length computations mixed up.