https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70988
Jakub Jelinek <jakub at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |jakub at gcc dot gnu.org --- Comment #2 from Jakub Jelinek <jakub at gcc dot gnu.org> --- At least #c1 is indeed a tree-ssa-strlen.c bug. It transforms a = ""; __builtin___strcat_chk (&a, "abc", 4); __builtin___strcat_chk (&a, "def", 4); __builtin___strcat_chk (&a, "ghi", 4); __builtin___strcat_chk (&a, "jkl", 4); into: a = ""; __builtin___memcpy_chk (&a, "abc", 4, 4); _9 = &a + 3; __builtin___memcpy_chk (_9, "def", 4, 4); _10 = &a + 6; __builtin___memcpy_chk (_10, "ghi", 4, 4); _11 = &a + 9; __builtin___memcpy_chk (_11, "jkl", 4, 4); which is wrong, we need to subtract the current known length of the destination string from the __strcat_chk BOS sizes to get the __memcpy_chk BOS size (and both have to be integers), otherwise we have to punt on the transformation (BOS can't be variable). So the above would be: a = ""; __builtin___memcpy_chk (&a, "abc", 4, 4); _9 = &a + 3; __builtin___memcpy_chk (_9, "def", 4, 1); _10 = &a + 6; __builtin___memcpy_chk (_10, "ghi", 4, 0); _11 = &a + 9; __builtin___memcpy_chk (_11, "jkl", 4, 0); For known variable length of destination string before __strcat_chk, the question is if we shouldn't transform it to memcpy instead with if (var_len + const_size >= strcat_bos) __chk_fail (); but we'd then might run into overflow issues and from the basic design principle that -D_FORTIFY_SOURCE=2 should provide only very cheap checks. So maybe use ADD_OVERFLOW too on the addition? The strcat -> memcpy transformation is important on the other side, would be bad if we lost it.