This invalid code (character char(n) is not a legal len value) gives an ICE down to r6, seems to be accepted by r5 : $ cat z1.f90 module m type t character(char(1)) :: a end type type(t) :: z = t('a') end $ gfortran-5 -c z1.f90 $ $ gfortran-11-20200628 -c z1.f90 f951: internal compiler error: Segmentation fault 0xbd215f crash_signal ../../gcc/toplev.c:328 0x696d8c mio_name_expr_t ../../gcc/fortran/module.c:2159 0x696d8c mio_expr ../../gcc/fortran/module.c:3567 0x697543 mio_charlen ../../gcc/fortran/module.c:2629 0x69763c mio_typespec ../../gcc/fortran/module.c:2687 0x696da0 mio_expr ../../gcc/fortran/module.c:3586 0x697543 mio_charlen ../../gcc/fortran/module.c:2629 0x69763c mio_typespec ../../gcc/fortran/module.c:2687 0x6979c5 mio_component ../../gcc/fortran/module.c:2920 0x6989da mio_component_list ../../gcc/fortran/module.c:2957 0x6989da mio_symbol ../../gcc/fortran/module.c:4416 0x698e3d write_symbol ../../gcc/fortran/module.c:5771 0x698fa2 write_symbol0 ../../gcc/fortran/module.c:5811 0x698f18 write_symbol0 ../../gcc/fortran/module.c:5790 0x698f18 write_symbol0 ../../gcc/fortran/module.c:5790 0x69bb04 write_module ../../gcc/fortran/module.c:6153 0x69bb04 dump_module ../../gcc/fortran/module.c:6283 0x69becd gfc_dump_module(char const*, int) ../../gcc/fortran/module.c:6340 0x6b5d26 gfc_parse_file() ../../gcc/fortran/parse.c:6457 0x7016ff gfc_be_parse_file ../../gcc/fortran/f95-lang.c:212
Confirmed from GCC8 up to master. My instrumented compiler gives ==36165==ERROR: AddressSanitizer: heap-use-after-free on address 0x604000001090 at pc 0x0001002a7c06 bp 0x7ffeefbfe5c0 sp 0x7ffeefbfe5b8 READ of size 8 at 0x604000001090 thread T0 #0 0x1002a7c05 in mio_expr(gfc_expr**) module.c:3560 #1 0x1002a9986 in mio_charlen(gfc_charlen**) module.c:2629 #2 0x1002aa123 in mio_typespec(gfc_typespec*) module.c:2687 #3 0x1002a7aec in mio_expr(gfc_expr**) module.c:3586 #4 0x1002a9986 in mio_charlen(gfc_charlen**) module.c:2629 #5 0x1002aa123 in mio_typespec(gfc_typespec*) module.c:2687 #6 0x1002ac779 in mio_component(gfc_component*, int) module.c:2920 #7 0x1002acf76 in mio_component_list(gfc_component**, int) module.c:2957 #8 0x1002b221e in mio_symbol(gfc_symbol*) module.c:4416 #9 0x1002b3416 in write_symbol(int, gfc_symbol*) module.c:5771 #10 0x1002bd091 in write_symbol0(gfc_symtree*) module.c:5811 #11 0x1002bcc9f in write_symbol0(gfc_symtree*) module.c:5790 #12 0x1002bcc9f in write_symbol0(gfc_symtree*) module.c:5790 #13 0x1002bd74a in write_module() module.c:6153 #14 0x1002bdc02 in dump_module(char const*, int) module.c:6283 #15 0x1002be369 in gfc_dump_module(char const*, int) module.c:6340 #16 0x100374c6f in gfc_parse_file() parse.c:6457 #17 0x10055a224 in gfc_be_parse_file() f95-lang.c:212 #18 0x106b46254 in compile_file() toplev.c:458 #19 0x106b552e3 in do_compile() toplev.c:2307 #20 0x10a42f19e in toplev::main(int, char**) toplev.c:2446 #21 0x10a933d44 in main main.c:39 #22 0x7fff6bb23cc8 in start+0x0 (libdyld.dylib:x86_64+0x1acc8) 0x604000001090 is located 0 bytes inside of 48-byte region [0x604000001090,0x6040000010c0) freed by thread T0 here: #0 0x15b8378f7 in wrap_free.part.0+0x97 (libasan.6.dylib:x86_64+0x4a8f7) #1 0x10050d6db in gfc_free_charlen(gfc_charlen*, gfc_charlen*) symbol.c:3990 #2 0x10050da95 in gfc_free_namespace(gfc_namespace*) symbol.c:4041 #3 0x1000d5a47 in gfc_match_char_spec(gfc_typespec*) decl.c:3506 #4 0x1000f171d in gfc_match_decl_type_spec(gfc_typespec*, int) decl.c:4166 #5 0x100105f3c in gfc_match_data_decl() decl.c:6126 #6 0x100354b42 in match_word(char const*, match (*)(), locus*) parse.c:65 #7 0x100361a89 in decode_statement() parse.c:376 #8 0x100363fdd in next_free() parse.c:1280 #9 0x10036499a in next_statement() parse.c:1512 #10 0x100369ab2 in parse_derived() parse.c:3343 #11 0x10036b617 in parse_spec(gfc_statement) parse.c:3883 #12 0x100373a04 in parse_module() parse.c:6116 #13 0x100374976 in gfc_parse_file() parse.c:6421 #14 0x10055a224 in gfc_be_parse_file() f95-lang.c:212 #15 0x106b46254 in compile_file() toplev.c:458 #16 0x106b552e3 in do_compile() toplev.c:2307 #17 0x10a42f19e in toplev::main(int, char**) toplev.c:2446 #18 0x10a933d44 in main main.c:39 #19 0x7fff6bb23cc8 in start+0x0 (libdyld.dylib:x86_64+0x1acc8) previously allocated by thread T0 here: #0 0x15b837fff in wrap_calloc+0xbf (libasan.6.dylib:x86_64+0x4afff) #1 0x109833754 in xcalloc xmalloc.c:162 #2 0x10050b457 in gfc_new_charlen(gfc_namespace*, gfc_charlen*) symbol.c:3954 #3 0x10044a874 in fixup_charlen(gfc_expr*) resolve.c:6078 #4 0x10041538e in gfc_resolve_expr(gfc_expr*) resolve.c:7108 #5 0x1001650df in gfc_reduce_init_expr(gfc_expr*) expr.c:3085 #6 0x1000d59b5 in gfc_match_char_spec(gfc_typespec*) decl.c:3496 #7 0x1000f171d in gfc_match_decl_type_spec(gfc_typespec*, int) decl.c:4166 #8 0x100105f3c in gfc_match_data_decl() decl.c:6126 #9 0x100354b42 in match_word(char const*, match (*)(), locus*) parse.c:65 #10 0x100361a89 in decode_statement() parse.c:376 #11 0x100363fdd in next_free() parse.c:1280 #12 0x10036499a in next_statement() parse.c:1512 #13 0x100369ab2 in parse_derived() parse.c:3343 #14 0x10036b617 in parse_spec(gfc_statement) parse.c:3883 #15 0x100373a04 in parse_module() parse.c:6116 #16 0x100374976 in gfc_parse_file() parse.c:6421 #17 0x10055a224 in gfc_be_parse_file() f95-lang.c:212 #18 0x106b46254 in compile_file() toplev.c:458 #19 0x106b552e3 in do_compile() toplev.c:2307 #20 0x10a42f19e in toplev::main(int, char**) toplev.c:2446 #21 0x10a933d44 in main main.c:39 #22 0x7fff6bb23cc8 in start+0x0 (libdyld.dylib:x86_64+0x1acc8) ... GCC7 combles the code without error.
The patch in PR 95025 fixes this issue.
> The patch in PR 95025 fixes this issue. The patch fixes the ICE, but I get the cryptic error f951: Fatal Error: Writing module 'm' at line 15 column 14: Bad type in constant expression compilation terminated.
On Sat, Jul 04, 2020 at 09:29:49AM +0000, dominiq at lps dot ens.fr wrote: > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96024 > > --- Comment #3 from Dominique d'Humieres <dominiq at lps dot ens.fr> --- > > The patch in PR 95025 fixes this issue. > > The patch fixes the ICE, but I get the cryptic error > > f951: Fatal Error: Writing module 'm' at line 15 column 14: Bad type in > constant expression > compilation terminated. > gfc_fatal_error() is used 17 times in module.c. This normally means that gfortran's error handling mechanism is not available at the time the error occrurred. It also be that in this case, the *.mod file and the namespace is too corrupted to try to continue.
(In reply to kargl from comment #2) > The patch in PR 95025 fixes this issue. PR 96025, I assume.
(In reply to Thomas Koenig from comment #5) > (In reply to kargl from comment #2) > > The patch in PR 95025 fixes this issue. > > PR 96025, I assume. Yes.
GCC 9.4 is being released, retargeting bugs to GCC 9.5.
GCC 9 branch is being closed
GCC 10.4 is being released, retargeting bugs to GCC 10.5.
I have a patch which is regtesting right now.
Submitted: https://gcc.gnu.org/pipermail/fortran/2023-February/058949.html
The master branch has been updated by Harald Anlauf <anlauf@gcc.gnu.org>: https://gcc.gnu.org/g:31303c9b5bab200754cdb7ef8cd91ae4918f3018 commit r13-6289-g31303c9b5bab200754cdb7ef8cd91ae4918f3018 Author: Harald Anlauf <anlauf@gmx.de> Date: Tue Feb 21 22:06:33 2023 +0100 Fortran: reject invalid CHARACTER length of derived type components [PR96024] gcc/fortran/ChangeLog: PR fortran/96024 * resolve.cc (resolve_component): The type of a CHARACTER length expression must be INTEGER. gcc/testsuite/ChangeLog: PR fortran/96024 * gfortran.dg/pr96024.f90: New test.
The releases/gcc-12 branch has been updated by Harald Anlauf <anlauf@gcc.gnu.org>: https://gcc.gnu.org/g:3f1ae4deb9c1524b2b1a5c9c4e751ea1c0f7478d commit r12-9221-g3f1ae4deb9c1524b2b1a5c9c4e751ea1c0f7478d Author: Harald Anlauf <anlauf@gmx.de> Date: Tue Feb 21 22:06:33 2023 +0100 Fortran: reject invalid CHARACTER length of derived type components [PR96024] gcc/fortran/ChangeLog: PR fortran/96024 * resolve.cc (resolve_component): The type of a CHARACTER length expression must be INTEGER. gcc/testsuite/ChangeLog: PR fortran/96024 * gfortran.dg/pr96024.f90: New test. (cherry picked from commit 31303c9b5bab200754cdb7ef8cd91ae4918f3018)
The releases/gcc-11 branch has been updated by Harald Anlauf <anlauf@gcc.gnu.org>: https://gcc.gnu.org/g:7db643a17e8c862b4c758fd69d62a45c6de43d38 commit r11-10559-g7db643a17e8c862b4c758fd69d62a45c6de43d38 Author: Harald Anlauf <anlauf@gmx.de> Date: Tue Feb 21 22:06:33 2023 +0100 Fortran: reject invalid CHARACTER length of derived type components [PR96024] gcc/fortran/ChangeLog: PR fortran/96024 * resolve.c (resolve_component): The type of a CHARACTER length expression must be INTEGER. gcc/testsuite/ChangeLog: PR fortran/96024 * gfortran.dg/pr96024.f90: New test. (cherry picked from commit 31303c9b5bab200754cdb7ef8cd91ae4918f3018)
The releases/gcc-10 branch has been updated by Harald Anlauf <anlauf@gcc.gnu.org>: https://gcc.gnu.org/g:22031c5868bbb434b51ea4010ccae0cf8c890d6b commit r10-11240-g22031c5868bbb434b51ea4010ccae0cf8c890d6b Author: Harald Anlauf <anlauf@gmx.de> Date: Tue Feb 21 22:06:33 2023 +0100 Fortran: reject invalid CHARACTER length of derived type components [PR96024] gcc/fortran/ChangeLog: PR fortran/96024 * resolve.c (resolve_component): The type of a CHARACTER length expression must be INTEGER. gcc/testsuite/ChangeLog: PR fortran/96024 * gfortran.dg/pr96024.f90: New test. (cherry picked from commit 31303c9b5bab200754cdb7ef8cd91ae4918f3018)
Fixed on all open branches. Closing. Thanks for the report!
The new testcase seems to fail on big-endian hosts. I've analyzed this on 11 branch: 3190 /* For a constant string constructor, make sure the length is 3191 correct; truncate of fill with blanks if needed. */ 3192 if (this_comp->ts.type == BT_CHARACTER && !this_comp->attr.allocatable 3193 && this_comp->ts.u.cl && this_comp->ts.u.cl->length 3194 && this_comp->ts.u.cl->length->expr_type == EXPR_CONSTANT 3195 && actual->expr->ts.type == BT_CHARACTER 3196 && actual->expr->expr_type == EXPR_CONSTANT) 3197 { 3198 ptrdiff_t c, e1; 3199 c = gfc_mpz_get_hwi (this_comp->ts.u.cl->length->value.integer); 3200 e1 = actual->expr->value.character.length; 3201 3202 if (c != e1) 3203 { 3204 ptrdiff_t i, to; 3205 gfc_char_t *dest; 3206 dest = gfc_get_wide_string (c + 1); *this_comp->ts.u.cl->length $20 = {expr_type = EXPR_CONSTANT, ts = {type = BT_CHARACTER, kind = 1 ... } Because it is a BT_CHARACTER EXPR_CONSTANTS, simplify_achar_char initialized it as 813 result = gfc_get_character_expr (kind, &e->where, NULL, 1); 814 result->value.character.string[0] = mpz_get_ui (e->value.integer); i.e. using the value.character union member. But the code assumes it is an integral constant instead and uses value.integer instead. p this_comp->ts.u.cl->length->value.character $22 = {length = 1, string = 0x2aa02ab2de0} where string points to array of unsigned int, big endian, so contains value 0x00000001 followed by garbage, which happens to be 0, so bytes 0, 0, 0, 1, 0, 0, 0, 0 Now p this_comp->ts.u.cl->length->value.integer $23 = {{_mp_alloc = 0, _mp_size = 1, _mp_d = 0x2aa02ab2de0}} (note, _mp_alloc and _mp_size are both 32-bit while length is 64-bit) and _mp_d points to array of mp_limb_t, which is unsigned long. So, this means c is 0x100000000 and we try to allocate 0x100000001 * 4 bytes == 17179869188. Now, on x86_64 string also points to array of unsigned int, but because it is little endian, the value 1 is there 1, 0, 0, 0, 0, 0, 0, 0, 0 (the last 4 bytes random garbage), so c is 1 rather than 0x100000000 and it allocates 2 * 4 bytes. So, presumably we need in addition to the && this_comp->ts.u.cl->length->expr_type == EXPR_CONSTANT check also test that the constant uses value.integer union member rather than some other one. Would && this_comp->ts.u.cl->length->ts.type == BT_INTEGER be the right test for it or something else?
(In reply to Jakub Jelinek from comment #17) > The new testcase seems to fail on big-endian hosts. I've analyzed this on > 11 branch: > [...] > So, presumably we need in addition to the > && this_comp->ts.u.cl->length->expr_type == EXPR_CONSTANT > check also test that the constant uses value.integer union member rather > than some other one. Would > && this_comp->ts.u.cl->length->ts.type == BT_INTEGER > be the right test for it or something else? The analysis look correct to me. I've seen myself other similar cases that just seemed to work on little-endian. This affects all branches since r8-6898-g04946c6b905572, so if your 1-line addition regtests OK, it is good for all open branches. Thanks for looking into this!
The master branch has been updated by Jakub Jelinek <jakub@gcc.gnu.org>: https://gcc.gnu.org/g:4cf6e322adc19f927859e0a5edfa93cec4b8c844 commit r14-1642-g4cf6e322adc19f927859e0a5edfa93cec4b8c844 Author: Jakub Jelinek <jakub@redhat.com> Date: Fri Jun 9 09:10:29 2023 +0200 fortran: Fix ICE on pr96024.f90 on big-endian hosts [PR96024] The pr96024.f90 testcase ICEs on big-endian hosts. The problem is that length->val.integer is accessed after checking length->expr_type == EXPR_CONSTANT, but it is a CHARACTER constant which uses length->val.character union member instead and on big-endian we end up reading constant 0x100000000 rather than some small number on little-endian and if target doesn't have enough memory for 4 times that (i.e. 16GB allocation), it ICEs. 2023-06-09 Jakub Jelinek <jakub@redhat.com> PR fortran/96024 * primary.cc (gfc_convert_to_structure_constructor): Only do constant string ctor length verification and truncation/padding if constant length has INTEGER type.
The releases/gcc-13 branch has been updated by Jakub Jelinek <jakub@gcc.gnu.org>: https://gcc.gnu.org/g:32c51d0911e8d1bdf3f60bc831794b7932416ccd commit r13-7431-g32c51d0911e8d1bdf3f60bc831794b7932416ccd Author: Jakub Jelinek <jakub@redhat.com> Date: Fri Jun 9 09:10:29 2023 +0200 fortran: Fix ICE on pr96024.f90 on big-endian hosts [PR96024] The pr96024.f90 testcase ICEs on big-endian hosts. The problem is that length->val.integer is accessed after checking length->expr_type == EXPR_CONSTANT, but it is a CHARACTER constant which uses length->val.character union member instead and on big-endian we end up reading constant 0x100000000 rather than some small number on little-endian and if target doesn't have enough memory for 4 times that (i.e. 16GB allocation), it ICEs. 2023-06-09 Jakub Jelinek <jakub@redhat.com> PR fortran/96024 * primary.cc (gfc_convert_to_structure_constructor): Only do constant string ctor length verification and truncation/padding if constant length has INTEGER type. (cherry picked from commit 4cf6e322adc19f927859e0a5edfa93cec4b8c844)
The releases/gcc-12 branch has been updated by Jakub Jelinek <jakub@gcc.gnu.org>: https://gcc.gnu.org/g:bc4adb88611cb17280ab15ac4e13ab1d05b11825 commit r12-9687-gbc4adb88611cb17280ab15ac4e13ab1d05b11825 Author: Jakub Jelinek <jakub@redhat.com> Date: Fri Jun 9 09:10:29 2023 +0200 fortran: Fix ICE on pr96024.f90 on big-endian hosts [PR96024] The pr96024.f90 testcase ICEs on big-endian hosts. The problem is that length->val.integer is accessed after checking length->expr_type == EXPR_CONSTANT, but it is a CHARACTER constant which uses length->val.character union member instead and on big-endian we end up reading constant 0x100000000 rather than some small number on little-endian and if target doesn't have enough memory for 4 times that (i.e. 16GB allocation), it ICEs. 2023-06-09 Jakub Jelinek <jakub@redhat.com> PR fortran/96024 * primary.cc (gfc_convert_to_structure_constructor): Only do constant string ctor length verification and truncation/padding if constant length has INTEGER type. (cherry picked from commit 4cf6e322adc19f927859e0a5edfa93cec4b8c844)
The releases/gcc-11 branch has been updated by Jakub Jelinek <jakub@gcc.gnu.org>: https://gcc.gnu.org/g:7f875e435b23dfb439bc7784cade4aebbd5d4a69 commit r11-10850-g7f875e435b23dfb439bc7784cade4aebbd5d4a69 Author: Jakub Jelinek <jakub@redhat.com> Date: Fri Jun 9 09:10:29 2023 +0200 fortran: Fix ICE on pr96024.f90 on big-endian hosts [PR96024] The pr96024.f90 testcase ICEs on big-endian hosts. The problem is that length->val.integer is accessed after checking length->expr_type == EXPR_CONSTANT, but it is a CHARACTER constant which uses length->val.character union member instead and on big-endian we end up reading constant 0x100000000 rather than some small number on little-endian and if target doesn't have enough memory for 4 times that (i.e. 16GB allocation), it ICEs. 2023-06-09 Jakub Jelinek <jakub@redhat.com> PR fortran/96024 * primary.c (gfc_convert_to_structure_constructor): Only do constant string ctor length verification and truncation/padding if constant length has INTEGER type. (cherry picked from commit 4cf6e322adc19f927859e0a5edfa93cec4b8c844)
The releases/gcc-10 branch has been updated by Jakub Jelinek <jakub@gcc.gnu.org>: https://gcc.gnu.org/g:f46b16ef25fec4f936724ca449259db5c3de0f54 commit r10-11441-gf46b16ef25fec4f936724ca449259db5c3de0f54 Author: Jakub Jelinek <jakub@redhat.com> Date: Fri Jun 9 09:10:29 2023 +0200 fortran: Fix ICE on pr96024.f90 on big-endian hosts [PR96024] The pr96024.f90 testcase ICEs on big-endian hosts. The problem is that length->val.integer is accessed after checking length->expr_type == EXPR_CONSTANT, but it is a CHARACTER constant which uses length->val.character union member instead and on big-endian we end up reading constant 0x100000000 rather than some small number on little-endian and if target doesn't have enough memory for 4 times that (i.e. 16GB allocation), it ICEs. 2023-06-09 Jakub Jelinek <jakub@redhat.com> PR fortran/96024 * primary.c (gfc_convert_to_structure_constructor): Only do constant string ctor length verification and truncation/padding if constant length has INTEGER type. (cherry picked from commit 4cf6e322adc19f927859e0a5edfa93cec4b8c844)
Fixed.