PR fortran/95090 - ICE: identifier overflow
authorHarald Anlauf <anlauf@gmx.de>
Fri, 29 May 2020 19:19:31 +0000 (21:19 +0200)
committerHarald Anlauf <anlauf@gmx.de>
Fri, 29 May 2020 19:19:31 +0000 (21:19 +0200)
The initial fix for this PR uncovered several latent issues with further
too small string buffers which showed up only when testing on i686.
Provide sufficiently large temporaries.

2020-05-29  Harald Anlauf  <anlauf@gmx.de>

gcc/fortran/
PR fortran/95090
* class.c (get_unique_type_string): Enlarge temporary for
name-mangling.  Use strncpy to prevent buffer overrun.
(get_unique_hashed_string): Enlarge temporary.
(gfc_hash_value): Enlarge temporary for name-mangling.

gcc/fortran/class.c

index 9aa3eb7282c42d5bbea58243093098e1b6553f69..db395624a16da697faa59d06e5aa86d31a494270 100644 (file)
@@ -479,11 +479,12 @@ gfc_class_initializer (gfc_typespec *ts, gfc_expr *init_expr)
 static void
 get_unique_type_string (char *string, gfc_symbol *derived)
 {
-  char dt_name[GFC_MAX_SYMBOL_LEN+1];
+  /* Provide sufficient space to hold "Pdtsymbol".  */
+  char dt_name[GFC_MAX_SYMBOL_LEN+4];
   if (derived->attr.unlimited_polymorphic)
     strcpy (dt_name, "STAR");
   else
-    strcpy (dt_name, gfc_dt_upper_string (derived->name));
+    strncpy (dt_name, gfc_dt_upper_string (derived->name), sizeof (dt_name));
   if (derived->attr.unlimited_polymorphic)
     sprintf (string, "_%s", dt_name);
   else if (derived->module)
@@ -501,7 +502,8 @@ get_unique_type_string (char *string, gfc_symbol *derived)
 static void
 get_unique_hashed_string (char *string, gfc_symbol *derived)
 {
-  char tmp[2*GFC_MAX_SYMBOL_LEN+2];
+  /* Provide sufficient space to hold "symbol_Pdtsymbol".  */
+  char tmp[2*GFC_MAX_SYMBOL_LEN+5];
   get_unique_type_string (&tmp[0], derived);
   /* If string is too long, use hash value in hex representation (allow for
      extra decoration, cf. gfc_build_class_symbol & gfc_find_derived_vtab).
@@ -523,7 +525,8 @@ unsigned int
 gfc_hash_value (gfc_symbol *sym)
 {
   unsigned int hash = 0;
-  char c[2*(GFC_MAX_SYMBOL_LEN+1)];
+  /* Provide sufficient space to hold "symbol_Pdtsymbol".  */
+  char c[2*GFC_MAX_SYMBOL_LEN+5];
   int i, len;
 
   get_unique_type_string (&c[0], sym);