> > > This breaks bootstrap: > > > > > > https://gcc.gnu.org/pipermail/gcc-regression/2020-May/072642.html > > > > > > ../../src-master/gcc/fortran/class.c:487:13: error: ‘char* > > > strncpy(char*, const char*, size_t)’ specified bound 67 equals > > > destination size [-Werror=stringop-truncation] > > > 487 | strncpy (dt_name, gfc_dt_upper_string (derived->name), > > > sizeof (dt_name)); > > > > So should one use the clumsy way: > > > > strncpy(buf, str, buflen - 1); > > if (buflen > 0) > > buf[buflen - 1]= '\0'; > > > > Or is there something more convenient that keeps gcc happy? > > Depends on what exactly you want to achieve, but strncpy is pretty much > always the wrong answer. > Do you really want to clear the rest of buf, when gfc_dt_upper_string > is much shorter? That is one thing that is only seldom useful from strncpy > behavior. The other is that it doesn't zero terminate on truncation. > I'd suggest e.g. remember gfc_dt_upper_string result in a temporary, > compute len = strnlen (res, sizeof (dt_name) - 1); > and then you can just memcpy and zero terminate buf[len] = '\0'; > Or do you ever want to truncate?
I'ld like to detect the situation that when somebody modifies name-mangling in a way that generates a buffer overrun during regtesting so that the temporaries to adjust are easier to find. After thinking about your and H.J.'s suggestions, the shortest solution I came up with is: diff --git a/gcc/fortran/class.c b/gcc/fortran/class.c index db395624a16..6d0924da2b8 100644 --- a/gcc/fortran/class.c +++ b/gcc/fortran/class.c @@ -484,7 +484,12 @@ get_unique_type_string (char *string, gfc_symbol *derived) if (derived->attr.unlimited_polymorphic) strcpy (dt_name, "STAR"); else - strncpy (dt_name, gfc_dt_upper_string (derived->name), sizeof (dt_name)); + { + dt_name[sizeof (dt_name)-1] = '\0'; + strcpy (dt_name, gfc_dt_upper_string (derived->name)); + if (dt_name[sizeof (dt_name)-1] != '\0') + gfc_internal_error ("get_unique_type_string: identifier overflow"); + } if (derived->attr.unlimited_polymorphic) sprintf (string, "_%s", dt_name); else if (derived->module) That would have given me a useful error on x86_64. Is this OK for master? Harald