gfortran 4.1.2/4.2.0/4.3.0 segfaults when compiling the following program: program initbug integer,parameter :: n0 = 3, n = 5 real(kind=8),parameter :: x0(n0) = (/ 0.0d0, 0.0d0, 0.0d0 /) real(kind=8),parameter :: x(n) = (/ -x0, x0(n0-1:1:-1) /) + 1.0d0 end program initbug Valgrind output: $ valgrind /home/r6144/apps/gcc-4.3.0-070903-bin/bin/../libexec/gcc/i386-pc-linux-gnu/4.3.0/f951 initbug.f90 -quiet -dumpbase initbug.f90 -march=pentium4 -mfpmath=sse -auxbase-strip initbug.o -g -O2 -Wall -W -Wno-unused -Wimplicit-interface -Wtabs -version -ffree-form -ffree-line-length-none -fimplicit-none -ffpe-trap=invalid,zero,overflow -fintrinsic-modules-path /home/r6144/apps/gcc-4.3.0-070903-bin/bin/../lib/gcc/i386-pc-linux-gnu/4.3.0/finclude -o /tmp/ccZfWmpd.s ==5331== Memcheck, a memory error detector. ==5331== Copyright (C) 2002-2006, and GNU GPL'd, by Julian Seward et al. ==5331== Using LibVEX rev 1658, a library for dynamic binary translation. ==5331== Copyright (C) 2004-2006, and GNU GPL'd, by OpenWorks LLP. ==5331== Using valgrind-3.2.1, a dynamic binary instrumentation framework. ==5331== Copyright (C) 2000-2006, and GNU GPL'd, by Julian Seward et al. ==5331== For more details, rerun with: -v ==5331== GNU F95 (GCC) version 4.3.0 20070902 (experimental) [trunk revision 128023] (i386-pc-linux-gnu) compiled by GNU C version 4.3.0 20070902 (experimental) [trunk revision 128023], GMP version 4.2.1, MPFR version 2.2.1. GGC heuristics: --param ggc-min-expand=63 --param ggc-min-heapsize=63256 ==5331== Invalid read of size 4 ==5331== at 0x84CCEDB: mpfr_cmp2 (in /home/r6144/apps/gcc-4.3.0-070903-bin/libexec/gcc/i386-pc-linux-gnu/4.3.0/f951) ==5331== by 0x84C6D35: mpfr_sub1 (in /home/r6144/apps/gcc-4.3.0-070903-bin/libexec/gcc/i386-pc-linux-gnu/4.3.0/f951) ==5331== by 0x84B9AB2: mpfr_add (in /home/r6144/apps/gcc-4.3.0-070903-bin/libexec/gcc/i386-pc-linux-gnu/4.3.0/f951) ==5331== by 0x804CB56: gfc_arith_plus (arith.c:657) ==5331== Address 0x812488 is not stack'd, malloc'd or (recently) free'd initbug.f90:0: internal compiler error: Segmentation fault Please submit a full bug report, with preprocessed source if appropriate. See <http://gcc.gnu.org/bugs.html> for instructions.
I don't see the ICE on PPC Darwin8, revision 128037, but the following modifed code gives a wrong answer: program initbug integer,parameter :: n0 = 3, n = 5 real(kind=8),parameter :: x0(n0) = (/ 2.0d0, 2.0d0, 2.0d0 /) real(kind=8),parameter :: x(n) = (/ -x0, x0(n0-1:1:-1) /) + 1.0d0 print *, x end program initbug gives -1.00000000000000 -1.00000000000000 -1.00000000000000 1.00000000000000 0.00000000000000 xlf and g95 gives: -1.00000000000000000 -1.00000000000000000 -1.00000000000000000 3.00000000000000000 3.00000000000000000 or -1. -1. -1. 3. 3. as I expect.
> I don't see the ICE on PPC Darwin8, revision 128037, but the following modifed > code gives a wrong answer: For me (4.3.0 20070903, r128037, x86_64-unknown-linux-gnu) both examples cause a segmentation fault in mpfr_cmp2. Interestingly, I don't get any failure if I run the program through valgrind.
If I try to "regtestify" the code (uncomment the commented line): program initbug integer,parameter :: n0 = 3, n = 5 real(kind=8),parameter :: x0(n0) = (/ 2.0d0, 2.0d0, 2.0d0 /) real(kind=8),parameter :: x(n) = (/ -x0, x0(n0-1:1:-1) /) + 1.0d0 print *, x ! if (any(x /= (/ -1.0d0, -1.0d0, -1.0d0, 3.0d0, 3.0d0 /))) call abort() end program initbug I get: [karma] f90/bug% gfc pr33288.f90 pr33288.f90:4.37: real(kind=8),parameter :: x(n) = (/ -x0, x0(n0-1:1:-1) /) + 1.0d0 1 Error: Array operands are incommensurate at (1)
The following does not ICE for me and produces the right result (note the extra "+0.0"): real,parameter :: x(n) = (/ -x0, x0(n0-1:1:-1) + 0.0 /) +1.0 analogously for (note extra "(...)"): real,parameter :: x(n) = (/ -x0, ( x0(n0-1:1:-1) ) /) +1.0 Seemingly, the array range x0(n0-1:1:-1) does not get properly simplified and thus ->value.real points to the nirvana.
I confirm that program initbug integer,parameter :: n0 = 3, n = 5 real(kind=8),parameter :: x0(n0) = (/ 2.0d0, 2.0d0, 2.0d0 /) real(kind=8),parameter :: x(n) = (/ -x0, x0(n0-1:1:-1) + 0.0d0 /) + 1.0d0 print *, x if (any(x /= (/ -1.0d0, -1.0d0, -1.0d0, 3.0d0, 3.0d0 /))) call abort() end program initbug works as expected.
(In reply to comment #4) > Seemingly, the array range x0(n0-1:1:-1) does not get properly simplified and > thus ->value.real points to the nirvana. Nope. I get an ICE for the following testcase: real, parameter :: x0(1) = 0 real, parameter :: x(1) = (/ x0 /) + 1 end The problem is that we come into gfc_arith_plus() with one operand being an EXPR_ARRAY, so looking at its value.real is wrong (if you want to do something with it, it's value.constructor that should be looked at). I guess reduce_binary_ac() should really look deeper: in the loop "for (c = head; c; c = c->next)", we should see whether c->expr is an EXPR_CONSTANT before calling eval(), and look deeper into it if it's an EXPR_ARRAY. (Though it's the first time I look at this code and array constructors, I might be misunderstanding it all.)
Mine. A straightforward patch following the idea laid in my previous comment fixes it. Index: arith.c =================================================================== --- arith.c (revision 128540) +++ arith.c (working copy) @@ -1288,7 +1288,11 @@ reduce_unary (arith (*eval) (gfc_expr *, for (c = head; c; c = c->next) { - rc = eval (c->expr, &r); + if (c->expr->expr_type == EXPR_CONSTANT) + rc = eval (c->expr, &r); + else + rc = reduce_unary (eval, c->expr, &r); + if (rc != ARITH_OK) break; @@ -1328,7 +1332,11 @@ reduce_binary_ac (arith (*eval) (gfc_exp for (c = head; c; c = c->next) { - rc = eval (c->expr, op2, &r); + if (c->expr->expr_type == EXPR_CONSTANT) + rc = eval (c->expr, op2, &r); + else + rc = reduce_binary_ac (eval, c->expr, op2, &r); + if (rc != ARITH_OK) break; @@ -1368,7 +1376,11 @@ reduce_binary_ca (arith (*eval) (gfc_exp for (c = head; c; c = c->next) { - rc = eval (op1, c->expr, &r); + if (c->expr->expr_type == EXPR_CONSTANT) + rc = eval (op1, c->expr, &r); + else + rc = reduce_binary_ca (eval, op1, c->expr, &r); + if (rc != ARITH_OK) break; @@ -1395,6 +1407,11 @@ reduce_binary_ca (arith (*eval) (gfc_exp } +/* We need a forward declaration of reduce_binary. */ +static arith reduce_binary (arith (*eval) (gfc_expr *, gfc_expr *, gfc_expr **), + gfc_expr *op1, gfc_expr *op2, gfc_expr **result); + + static arith reduce_binary_aa (arith (*eval) (gfc_expr *, gfc_expr *, gfc_expr **), gfc_expr *op1, gfc_expr *op2, gfc_expr **result) @@ -1421,7 +1438,7 @@ reduce_binary_aa (arith (*eval) (gfc_exp break; } - rc = eval (c->expr, d->expr, &r); + rc = reduce_binary (eval, c->expr, d->expr, &r); if (rc != ARITH_OK) break;
Subject: Bug 33288 Author: fxcoudert Date: Thu Sep 20 21:58:23 2007 New Revision: 128632 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=128632 Log: PR fortran/33288 * arith.c (reduce_unary, reduce_binary_ac, reduce_binary_ca, reduce_binary_aa): Call ourselves recursively if an element of the constructor is itself a constant array. * gfortran.dg/array_constructor_19.f90: New test. Added: trunk/gcc/testsuite/gfortran.dg/array_constructor_19.f90 Modified: trunk/gcc/fortran/ChangeLog trunk/gcc/fortran/arith.c trunk/gcc/testsuite/ChangeLog
Fixed.