Bug 95090 - ICE: identifier overflow: 129
Summary: ICE: identifier overflow: 129
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: fortran (show other bugs)
Version: 11.0
: P4 normal
Target Milestone: ---
Assignee: anlauf
URL:
Keywords: ice-on-valid-code
Depends on:
Blocks:
 
Reported: 2020-05-12 16:43 UTC by G. Steinmetz
Modified: 2020-06-05 20:53 UTC (History)
4 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2020-05-26 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description G. Steinmetz 2020-05-12 16:43:07 UTC
Switches between name length 54 (ok) and 55 (ICE) :


$ cat z1_54.f90
module m23456789012345678901234567890123456789012345678901234
   type t23456789012345678901234567890123456789012345678901234 &
      (n23456789012345678901234567890123456789012345678901234)
      integer, len :: n23456789012345678901234567890123456789012345678901234 = 8
   end type
   integer :: a23456789012345678901234567890123456789012345678901234
   integer :: b23456789012345678901234567890123456789012345678901234(3)[*]
   data b23456789012345678901234567890123456789012345678901234 /1,2,3/
contains
   subroutine s23456789012345678901234567890123456789012345678901234
      type(t23456789012345678901234567890123456789012345678901234 &
         (n23456789012345678901234567890123456789012345678901234)) :: &
         z23456789012345678901234567890123456789012345678901234
   end
end


$ cat z1_55.f90
module m234567890123456789012345678901234567890123456789012345
   type t234567890123456789012345678901234567890123456789012345 &
      (n234567890123456789012345678901234567890123456789012345)
      integer, len :: n234567890123456789012345678901234567890123456789012345 = 8
   end type
   integer :: a234567890123456789012345678901234567890123456789012345
   integer :: b234567890123456789012345678901234567890123456789012345(3)[*]
   data b234567890123456789012345678901234567890123456789012345 /1,2,3/
contains
   subroutine s234567890123456789012345678901234567890123456789012345
      type(t234567890123456789012345678901234567890123456789012345 &
         (n234567890123456789012345678901234567890123456789012345)) :: &
         z234567890123456789012345678901234567890123456789012345
   end
end


$ cat z1_63.f90
module m23456789012345678901234567890123456789012345678901234567890123
   type t23456789012345678901234567890123456789012345678901234567890123 &
      (n23456789012345678901234567890123456789012345678901234567890123)
      integer, len :: n23456789012345678901234567890123456789012345678901234567890123 = 8
   end type
   integer :: a23456789012345678901234567890123456789012345678901234567890123
   integer :: b23456789012345678901234567890123456789012345678901234567890123(3)[*]
   data b23456789012345678901234567890123456789012345678901234567890123 /1,2,3/
contains
   subroutine s23456789012345678901234567890123456789012345678901234567890123
      type(t23456789012345678901234567890123456789012345678901234567890123 &
         (n23456789012345678901234567890123456789012345678901234567890123)) :: &
         z23456789012345678901234567890123456789012345678901234567890123
   end
end


$ cat z1_63_clean.f90
module m23456789012345678901234567890123456789012345678901234567890123
   type t23456789012345678901234567890123456789012345678901234567890123 &
      (n23456789012345678901234567890123456789012345678901234567890123)
      integer, len :: n23456789012345678901234567890123456789012345678901234567890123 = 8
   end type
   integer :: a23456789012345678901234567890123456789012345678901234567890123
   integer :: b23456789012345678901234567890123456789012345678901234567890123(3)[*]
   data b23456789012345678901234567890123456789012345678901234567890123 /1,2,3/
contains
   subroutine s23456789012345678901234567890123456789012345678901234567890123
      type(t23456789012345678901234567890123456789012345678901234567890123 &
         (3)) :: &
         z23456789012345678901234567890123456789012345678901234567890123
   end
end


$ gfortran-11-20200510 -c z1_54.f90 -fcoarray=lib
$ gfortran-11-20200510 -c z1_55.f90 -fcoarray=single
$
$ gfortran-11-20200510 -c z1_55.f90 -fcoarray=lib
f951: internal compiler error: identifier overflow: 129
0x64db59 gfc_report_diagnostic
        ../../gcc/fortran/error.c:782
0x64f27a gfc_internal_error(char const*, ...)
        ../../gcc/fortran/error.c:1402
0x676b1f gfc_get_string(char const*, ...)
        ../../gcc/fortran/iresolve.c:69
0x71bb8a gfc_build_qualified_array
        ../../gcc/fortran/trans-decl.c:994
0x720d24 gfc_get_symbol_decl(gfc_symbol*)
        ../../gcc/fortran/trans-decl.c:1793
0x723b58 gfc_create_module_variable
        ../../gcc/fortran/trans-decl.c:5297
0x6e2f72 do_traverse_symtree
        ../../gcc/fortran/symbol.c:4147
0x72435b gfc_generate_module_vars(gfc_namespace*)
        ../../gcc/fortran/trans-decl.c:5796
0x6fed94 gfc_generate_module_code(gfc_namespace*)
        ../../gcc/fortran/trans.c:2238
0x6abd11 translate_all_program_units
        ../../gcc/fortran/parse.c:6293
0x6abd11 gfc_parse_file()
        ../../gcc/fortran/parse.c:6545
0x6f7a7f gfc_be_parse_file
        ../../gcc/fortran/f95-lang.c:210
Comment 1 anlauf 2020-05-26 21:04:44 UTC
Confirmed.

The fix is to provide a sufficiently large buffer:

diff --git a/gcc/fortran/iresolve.c b/gcc/fortran/iresolve.c
index 7ecb6595f59..df4f2265c58 100644
--- a/gcc/fortran/iresolve.c
+++ b/gcc/fortran/iresolve.c
@@ -47,7 +47,8 @@ along with GCC; see the file COPYING3.  If not see
 const char *
 gfc_get_string (const char *format, ...)
 {
-  char temp_name[128];
+  /* Provide sufficient space to hold "_F.caf_token__symbol_MOD_symbol".  */
+  char temp_name[14 + GFC_MAX_SYMBOL_LEN + 5 + GFC_MAX_SYMBOL_LEN + 1];
   const char *str;
   va_list ap;
   tree ident;
Comment 2 GCC Commits 2020-05-27 19:20:47 UTC
The master branch has been updated by Harald Anlauf <anlauf@gcc.gnu.org>:

https://gcc.gnu.org/g:c949ec9c4e88d2ff6dbd5b179abddf3703129577

commit r11-670-gc949ec9c4e88d2ff6dbd5b179abddf3703129577
Author: Harald Anlauf <anlauf@gmx.de>
Date:   Wed May 27 21:20:24 2020 +0200

    PR fortran/95090 - ICE: identifier overflow
    
    For long module name, derive type and component name, the generated
    name-mangled symbol did not fit into a buffer when coarrays were
    enabled.  Provide sufficiently large temporary.
    
    2020-05-27  Harald Anlauf  <anlauf@gmx.de>
    
    gcc/fortran/
            PR fortran/95090
            * iresolve.c (gfc_get_string): Enlarge temporary for
            name-mangling.
    
    gcc/testsuite/
            PR fortran/95090
            * gfortran.dg/pr95090.f90: New test.
Comment 3 anlauf 2020-05-27 19:22:01 UTC
Fixed on master for gcc-11.

Thanks for the report!
Comment 4 Manfred Schwarb 2020-05-28 08:39:24 UTC
This breaks for me in i686, see
http://gfortran.meteodat.ch/download/i686/nightlies/gcc-trunk-20200528-gfe7ebef7fe4f9acb79658ed9db0749b07efc3105-README.txt

See also HJ's test in https://gcc.gnu.org/pipermail/gcc-testresults/2020-May/562121.html

x86_64 seems is OK. Error message is not really revealing:

Executing on host: /tmp/gcc-trunk-32bit-build/gcc/testsuite/gfortran2/../../gfortran -B/tmp/gcc-trunk-32bit-build/gcc/testsuite/gfortran2/../../ -B/tmp/gcc-trunk-32bit-build/i686-linux/./libgfortran/ /tmp/gcc-trunk-source/gcc/gcc/testsuite/gfortran.dg/pr95090.f90    -fno-diagnostics-show-caret -fno-diagnostics-show-line-numbers -fdiagnostics-color=never  -fdiagnostics-urls=never  -fno-diagnostics-show-caret -fno-diagnostics-show-line-numbers -fdiagnostics-color=never  -fdiagnostics-urls=never    -O  -fcoarray=lib -fsecond-underscore -S -o pr95090.s    (timeout = 300)
spawn -ignore SIGHUP /tmp/gcc-trunk-32bit-build/gcc/testsuite/gfortran2/../../gfortran -B/tmp/gcc-trunk-32bit-build/gcc/testsuite/gfortran2/../../ -B/tmp/gcc-trunk-32bit-build/i686-linux/./libgfortran/ /tmp/gcc-trunk-source/gcc/gcc/testsuite/gfortran.dg/pr95090.f90 -fno-diagnostics-show-caret -fno-diagnostics-show-line-numbers -fdiagnostics-color=never -fdiagnostics-urls=never -fno-diagnostics-show-caret -fno-diagnostics-show-line-numbers -fdiagnostics-color=never -fdiagnostics-urls=never -O -fcoarray=lib -fsecond-underscore -S -o pr95090.s
f951: internal compiler error: Segmentation fault
0x83cf0ac ???
	../sysdeps/i386/start.S:117
Please submit a full bug report,
with preprocessed source if appropriate.
Please include the complete backtrace with any bug report.
See <https://gcc.gnu.org/bugs/> for instructions.
compiler exited with status 1
FAIL: gfortran.dg/pr95090.f90   -O  (internal compiler error)
Comment 5 Manfred Schwarb 2020-05-28 09:31:13 UTC
gdb shows:

Program received signal SIGSEGV, Segmentation fault.
0xf7aa5162 in __strlen_sse2_bsf () from /lib/libc.so.6
#0  0xf7aa5162 in __strlen_sse2_bsf () from /lib/libc.so.6
#1  0x083e6def in get_unique_hashed_string(char*, gfc_symbol*) ()
#2  0x083e7754 in gfc_find_derived_vtab(gfc_symbol*) ()
#3  0x0847ef21 in resolve_fl_derived(gfc_symbol*) ()
#4  0x0847b857 in resolve_symbol(gfc_symbol*) ()
#5  0x084a6a10 in do_traverse_symtree(gfc_symtree*, void (*)(gfc_symtree*), void (*)(gfc_symbol*)) ()
#6  0x084870b7 in resolve_types(gfc_namespace*) ()
#7  0x0847a825 in gfc_resolve(gfc_namespace*) ()
#8  0x0846db96 in gfc_parse_file() ()
#9  0x084bdd27 in gfc_be_parse_file() ()
#10 0x08a3a6de in compile_file() ()
#11 0x083c8b15 in toplev::main(int, char**) ()
#12 0x083ccc21 in main ()
Comment 6 anlauf 2020-05-28 17:26:30 UTC
(In reply to Manfred Schwarb from comment #5)
> gdb shows:
> 
> Program received signal SIGSEGV, Segmentation fault.
> 0xf7aa5162 in __strlen_sse2_bsf () from /lib/libc.so.6
> #0  0xf7aa5162 in __strlen_sse2_bsf () from /lib/libc.so.6
> #1  0x083e6def in get_unique_hashed_string(char*, gfc_symbol*) ()

Can you please try the following patch for me?

diff --git a/gcc/fortran/class.c b/gcc/fortran/class.c
index 9aa3eb7282c..065cd691a73 100644
--- a/gcc/fortran/class.c
+++ b/gcc/fortran/class.c
@@ -501,7 +501,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).

Thanks.
Comment 7 anlauf 2020-05-28 18:50:47 UTC
Reopening.
Comment 8 Manfred Schwarb 2020-05-28 23:36:49 UTC
I even tried "char tmp[2*GFC_MAX_SYMBOL_LEN+800];" but it
still fails.
Comment 9 Manfred Schwarb 2020-05-29 10:58:05 UTC
I sprinkled some printf's into get_unique_type_string():

XXderived->name: strlen=63; t2345678901234567890123456789012345678901234567890123456789_123
XXdt_name: strlen=63; T2345678901234567890123456789012345678901234567890123456789_123
XXderived->ns->proc_name->name: strlen=63; m2345678901234567890123456789012345678901234567890123456789_123
XXstring: strlen=127; m2345678901234567890123456789012345678901234567890123456789_123_T2345678901234567890123456789012345678901234567890123456789_123
XXderived->name: strlen=66; Pdtt2345678901234567890123456789012345678901234567890123456789_123
XXdt_name: strlen=66; Pdtt2345678901234567890123456789012345678901234567890123456789_123
XXderived->ns->proc_name->name: strlen=63; m2345678901234567890123456789012345678901234567890123456789_123
XXstring: strlen=130; m2345678901234567890123456789012345678901234567890123456789_123_Pdtt2345678901234567890123456789012345678901234567890123456789_123
XXderived->name: strlen=66; Pdtt2345678901234567890123456789012345678901234567890123456789_123
XXdt_name: strlen=66; Pdtt2345678901234567890123456789012345678901234567890123456789_123
XXderived->ns->proc_name->name: strlen=63; m2345678901234567890123456789012345678901234567890123456789_123
XXstring: strlen=130; m2345678901234567890123456789012345678901234567890123456789_123_Pdtt2345678901234567890123456789012345678901234567890123456789_123


If both string lengths get upped by 3, things get working:

 get_unique_type_string (char *string, gfc_symbol *derived)
 {
-  char dt_name[GFC_MAX_SYMBOL_LEN+1];
+  char dt_name[GFC_MAX_SYMBOL_LEN+4];

....

 get_unique_hashed_string (char *string, gfc_symbol *derived)
 {
-  char tmp[2*GFC_MAX_SYMBOL_LEN+2];
+  char tmp[2*GFC_MAX_SYMBOL_LEN+5];


So with these changes, I get no ICE anymore.
Comment 10 Manfred Schwarb 2020-05-29 14:33:38 UTC
I just tried to build a compiler with "-fno-omit-frame-pointer" to
get potentially better backtraces, but then the ICE vanishes ...

Is there a way to get useful backtraces? "--enable-checking=yes,extra"
seems not to be enough...
Comment 11 anlauf 2020-05-29 18:49:34 UTC
(In reply to Manfred Schwarb from comment #10)
> Is there a way to get useful backtraces? "--enable-checking=yes,extra"
> seems not to be enough...

Maybe some "fortify" option or a "sanitized" version of the compiler?

I tried valgrind, but failed.

Then I decided to do it the hard way running the example under gdb,
and found a third function which needs adjustment.

diff --git a/gcc/fortran/class.c b/gcc/fortran/class.c
index 9aa3eb7282c..db395624a16 100644
--- a/gcc/fortran/class.c
+++ b/gcc/fortran/class.c
@@ -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);


I have added one protection using strncpy to avoid a buffer overflow.
One could "protect" the temporary buffers by setting the last byte to \0
and add an assert later to detect an overrun.

I'll regtest the above and commit as "obvious" later.

Thanks, Manfred, for providing pointers.
Comment 12 GCC Commits 2020-05-29 19:19:55 UTC
The master branch has been updated by Harald Anlauf <anlauf@gcc.gnu.org>:

https://gcc.gnu.org/g:7deca8c0b3765787627b11387b56b97b01a8bf33

commit r11-731-g7deca8c0b3765787627b11387b56b97b01a8bf33
Author: Harald Anlauf <anlauf@gmx.de>
Date:   Fri May 29 21:19:31 2020 +0200

    PR fortran/95090 - ICE: identifier overflow
    
    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.
Comment 13 GCC Commits 2020-05-30 18:51:26 UTC
The master branch has been updated by Harald Anlauf <anlauf@gcc.gnu.org>:

https://gcc.gnu.org/g:bf5fbbbd8c9a3385c1083cc80683bdb0195b1ffc

commit r11-742-gbf5fbbbd8c9a3385c1083cc80683bdb0195b1ffc
Author: Harald Anlauf <anlauf@gmx.de>
Date:   Sat May 30 20:50:59 2020 +0200

    PR fortran/95090 - ICE: identifier overflow
    
    Implement buffer overrun check for temporary that holds mangled names.
    
    2020-05-30  Harald Anlauf  <anlauf@gmx.de>
    
    gcc/fortran/
            PR fortran/95090
            * class.c (get_unique_type_string): Use buffer overrun check.
Comment 14 GCC Commits 2020-06-05 19:32:37 UTC
The releases/gcc-10 branch has been updated by Harald Anlauf <anlauf@gcc.gnu.org>:

https://gcc.gnu.org/g:2ee8913bbbb0c278169b18b0123316ea4745120f

commit r10-8251-g2ee8913bbbb0c278169b18b0123316ea4745120f
Author: Harald Anlauf <anlauf@gmx.de>
Date:   Wed May 27 21:20:24 2020 +0200

    PR fortran/95090 - ICE: identifier overflow
    
    For long module name, derive type and component name, the generated
    name-mangled symbol did not fit into a buffer when coarrays were
    enabled.  Provide sufficiently large temporary.
    
    2020-05-27  Harald Anlauf  <anlauf@gmx.de>
    
    gcc/fortran/
            PR fortran/95090
            * iresolve.c (gfc_get_string): Enlarge temporary for
            name-mangling.
    
    gcc/testsuite/
            PR fortran/95090
            * gfortran.dg/pr95090.f90: New test.
    
    (cherry picked from commit c949ec9c4e88d2ff6dbd5b179abddf3703129577)
Comment 15 GCC Commits 2020-06-05 19:32:42 UTC
The releases/gcc-10 branch has been updated by Harald Anlauf <anlauf@gcc.gnu.org>:

https://gcc.gnu.org/g:78c4b06ac3df51c460de835917549c8555ee4eaf

commit r10-8252-g78c4b06ac3df51c460de835917549c8555ee4eaf
Author: Harald Anlauf <anlauf@gmx.de>
Date:   Fri May 29 21:19:31 2020 +0200

    PR fortran/95090 - ICE: identifier overflow
    
    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.
    
    (cherry picked from commit 7deca8c0b3765787627b11387b56b97b01a8bf33)
Comment 16 GCC Commits 2020-06-05 19:32:48 UTC
The releases/gcc-10 branch has been updated by Harald Anlauf <anlauf@gcc.gnu.org>:

https://gcc.gnu.org/g:b3c17dfef86311a8b27b8e19854fd44cf8da29ee

commit r10-8253-gb3c17dfef86311a8b27b8e19854fd44cf8da29ee
Author: Harald Anlauf <anlauf@gmx.de>
Date:   Sat May 30 20:50:59 2020 +0200

    PR fortran/95090 - ICE: identifier overflow
    
    Implement buffer overrun check for temporary that holds mangled names.
    
    2020-05-30  Harald Anlauf  <anlauf@gmx.de>
    
    gcc/fortran/
            PR fortran/95090
            * class.c (get_unique_type_string): Use buffer overrun check.
    
    (cherry picked from commit bf5fbbbd8c9a3385c1083cc80683bdb0195b1ffc)
Comment 17 anlauf 2020-06-05 20:53:04 UTC
Fixed on master for GCC-11 and 10-branch.

A backport to 9-branch would need some manual work.  As this is not a
regression, not done.

Thanks for the report!