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
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;
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.
Fixed on master for gcc-11. Thanks for the report!
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)
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 ()
(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.
Reopening.
I even tried "char tmp[2*GFC_MAX_SYMBOL_LEN+800];" but it still fails.
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.
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...
(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.
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.
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.
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)
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)
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)
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!