PR fortran/95826 - Buffer overflows with PDTs and long symbols
authorHarald Anlauf <anlauf@gmx.de>
Thu, 25 Jun 2020 18:32:13 +0000 (20:32 +0200)
committerHarald Anlauf <anlauf@gmx.de>
Thu, 25 Jun 2020 18:32:13 +0000 (20:32 +0200)
With PDTs (parameterized derived types), name mangling results in variably
long internal symbols.  Use a dynamic buffer instead of a fixed-size one.

gcc/fortran/
PR fortran/95826
* decl.c (gfc_match_decl_type_spec): Replace a fixed size
buffer by a pointer and reallocate if necessary.

gcc/fortran/decl.c
gcc/testsuite/gfortran.dg/pr95826.f90 [new file with mode: 0644]

index c27cfacf2e4ec10d98a300d6ec38e1cdb79de068..ac1f63f66e0e844d5341b094bcc5830d9cca1b6c 100644 (file)
@@ -4095,7 +4095,7 @@ match
 gfc_match_decl_type_spec (gfc_typespec *ts, int implicit_flag)
 {
   /* Provide sufficient space to hold "pdtsymbol".  */
-  char name[GFC_MAX_SYMBOL_LEN + 1 + 3];
+  char *name = XALLOCAVEC (char, GFC_MAX_SYMBOL_LEN + 1);
   gfc_symbol *sym, *dt_sym;
   match m;
   char c;
@@ -4286,8 +4286,10 @@ gfc_match_decl_type_spec (gfc_typespec *ts, int implicit_flag)
          gcc_assert (!sym->attr.pdt_template && sym->attr.pdt_type);
          ts->u.derived = sym;
          const char* lower = gfc_dt_lower_string (sym->name);
-         size_t len = strnlen (lower, sizeof (name));
-         gcc_assert (len < sizeof (name));
+         size_t len = strlen (lower);
+         /* Reallocate with sufficient size.  */
+         if (len > GFC_MAX_SYMBOL_LEN)
+           name = XALLOCAVEC (char, len + 1);
          memcpy (name, lower, len);
          name[len] = '\0';
        }
diff --git a/gcc/testsuite/gfortran.dg/pr95826.f90 b/gcc/testsuite/gfortran.dg/pr95826.f90
new file mode 100644 (file)
index 0000000..8de04e6
--- /dev/null
@@ -0,0 +1,20 @@
+! { dg-do compile }
+! { dg-options "-fsecond-underscore" }
+! PR fortran/95826 - ICE in gfc_match_decl_type_spec, at fortran/decl.c:4290
+
+program p
+  type t2345678901234567890123456789012345678901234567890123456789_123 &
+      (a2345678901234567890123456789012345678901234567890123456789_123, &
+       b2345678901234567890123456789012345678901234567890123456789_123)
+     integer, kind :: &
+       a2345678901234567890123456789012345678901234567890123456789_123
+     integer, len :: &
+       b2345678901234567890123456789012345678901234567890123456789_123
+  end type
+  integer, parameter :: &
+       n2345678901234567890123456789012345678901234567890123456789_123 = 16
+  type(t2345678901234567890123456789012345678901234567890123456789_123 &
+      (n2345678901234567890123456789012345678901234567890123456789_123,:)), &
+       allocatable :: &
+       x2345678901234567890123456789012345678901234567890123456789_123
+end