Bug 50410 - [4.9/5/6 Regression] ICE in record_reference
Summary: [4.9/5/6 Regression] ICE in record_reference
Status: NEW
Alias: None
Product: gcc
Classification: Unclassified
Component: fortran (show other bugs)
Version: 4.8.0
: P4 normal
Target Milestone: 4.9.4
Assignee: Not yet assigned to anyone
Keywords: ice-on-invalid-code
Depends on:
Reported: 2011-09-15 08:40 UTC by Vittorio Zecca
Modified: 2015-06-26 20:06 UTC (History)
2 users (show)

See Also:
Known to work:
Known to fail:
Last reconfirmed: 2011-09-15 00:00:00

just compile it (115 bytes, text/plain)
2011-09-15 08:40 UTC, Vittorio Zecca
Draft patch (986 bytes, patch)
2011-10-17 21:20 UTC, Tobias Burnus
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Vittorio Zecca 2011-09-15 08:40:49 UTC
Created attachment 25286 [details]
just compile it

ICE in record_reference
Comment 1 Dominique d'Humieres 2011-09-15 11:08:55 UTC
Confirmed on 4.6.1 and trunk:

pr50410.f90:7:0: internal compiler error: in record_reference, at cgraphbuild.c:67

no ICE on 4.4.6 and 4.5.3 (no error). g95 gives the following error:

In file pr50410.f90:6

      data  u%g /1/
Error: Can't dereference POINTER in DATA statement at (1)
Comment 2 Vittorio Zecca 2011-09-18 17:38:10 UTC
The following produces a Segmentation fault in gfc_conv_structure (r178925)

      type t
       integer g
      end type
      type(t) :: u=t(1)
      data u%g /2/
Comment 3 Dominique d'Humieres 2011-09-18 18:20:57 UTC
The problem for the code in comment #2 seems different:
it gives a segmentation fault with 4.6.1 and trunk and an ICE with 4.4.6 and 4.5.3:

f951: internal compiler error: in formalize_structure_cons, at fortran/data.c:(756|755)

g95 gives the following error

In file pr50410_1.f90:5

      data u%g /2/
Error: Variable 'u' at (1) already has an initialization
Comment 4 kargl 2011-09-18 23:31:53 UTC
(In reply to comment #2)
> The following produces a Segmentation fault in gfc_conv_structure (r178925)
>       type t
>        integer g
>       end type
>       type(t) :: u=t(1)
>       data u%g /2/
>       end

The code is invalid and so gfortran can do anything that it
wishes, including segfault.

5.2.5 Data Statement

  A variable, or part of a variable, shall not be explicitly
  initialized more than once in a program.
Comment 5 janus 2011-09-21 16:58:29 UTC
(In reply to comment #4)
> The code is invalid and so gfortran can do anything that it
> wishes, including segfault.

Well, no. An ICE on invalid code may not be as bad as an ICE on valid code, but it's still a bug. gfortran should give a meaningful error message.
Comment 6 Tobias Burnus 2011-10-17 16:38:28 UTC
To check:
- Pointer attribute in the part ref - or an allocate attribute.
- Whether there is already some initialization.
  If one uses a constructor, it affects the whole variable,
  but mixing different data statements is OK as long as different
  parts are initialized.
- If one directly access the variable: Pointer init is only OK for null()

Example for the last item:
      integer, pointer :: u
      data u /1/  ! Accepted, but probably shouldn't
      ! data u/null()/ ! Probably OK (and currently accepted).

I think it could be sufficient to check decl.c's var_element though it might fail if one initializes a DT piecewise; if so, one needs to add a check to data.c or modify something else in decl.c
Comment 7 kargl 2011-10-17 17:36:33 UTC
(In reply to comment #2)
> The following produces a Segmentation fault in gfc_conv_structure (r178925)
>       type t
>        integer g
>       end type
>       type(t) :: u=t(1)
>       data u%g /2/
>       end

The following patch removes the seqfault.  If one adds
'print *, u%g' before end and compiles the resulting
program, then one gets 1.  This is acceptable, IMHO,
because the code is invalid.

Index: trans-expr.c
--- trans-expr.c        (revision 180099)
+++ trans-expr.c        (working copy)
@@ -4747,7 +4747,7 @@ gfc_conv_structure (gfc_se * se, gfc_exp
   cm = expr->ts.u.derived->components;
   for (c = gfc_constructor_first (expr->value.constructor);
-       c; c = gfc_constructor_next (c), cm = cm->next)
+       c && cm; c = gfc_constructor_next (c), cm = cm->next)
       /* Skip absent members in default initializers and allocatable
         components.  Although the latter have a default initializer
Comment 8 Tobias Burnus 2011-10-17 21:20:25 UTC
Created attachment 25534 [details]
Draft patch

The attached patch should fix all issues; however, I think the error message text can be improved. Additionally, one should re-check the standard and add some more test cases.
Comment 9 Tobias Burnus 2011-10-18 07:23:10 UTC
From the standard:
"C568 (R536) A data-i-do-object or a variable that appears as a
 data-stmt-object shall not be an object designator in which a
 pointer appears other than as the entire rightmost part-ref."

"C567 (R536) A variable whose designator appears as a
 data-stmt-object or a data-i-do-object shall not be a dummy
 argument, accessed by use or host association, in a named
 common block unless the DATA statement is in a block data
 program unit, in blank common, a function name, a function
 result name, an automatic object, or an allocatable variable."

To be fixed beyond the patch of attachment 25534 [details]
* ICE below (1) for init of DT with default init
* ICE below (2) with structure constructor, which initializes a pointer
(plus: test cases, revised error message wording)
* (3) Pointer init in DATA: Also "initial-data-target" is allowed

For the pointer init, see also PR 45290.

! =============== (1) =======================
module m
type t
  integer :: a  = 7
end type t
type t2
  integer :: b
end type t2
end module m

use m
implicit type(t)(x), type(t2)(y)
! ICE in trans:
! Invalid as "nonpointer object has default initialization"
DATA x%a/8/

! OK:
!DATA y%b/5/
!type(t2) :: y = t2(7) ! { dg-error "initializer already appears in a DATA statement" }
! ============= (2) =========================
module m
  type t
    integer :: a
    integer, pointer :: bar
  end type t
end module m

subroutine test()
  use m
  type(t) :: x ! = t(4, null()) ! OK
 DATA x/t(4, null())/ ! ICE in the middle end
end subroutine test
! ============= (3) =========================
type t
  integer, pointer :: ptr
end type t
integer, target, save :: tgt

! Version A:
!type(t) :: x = t(tgt)
! Rejected with "has not been declared or is a variable,
!         which does not reduce to a constant expression"

! Version 2
type(t) :: x
DATA x%ptr /tgt/ ! error "must be a PARAMETER in DATA statement"

tgt = 7
print *, ptr
Comment 10 Jakub Jelinek 2011-10-26 17:13:37 UTC
GCC 4.6.2 is being released.
Comment 12 Jakub Jelinek 2012-03-01 14:38:32 UTC
GCC 4.6.3 is being released.
Comment 13 Jakub Jelinek 2013-04-12 15:16:50 UTC
GCC 4.6.4 has been released and the branch has been closed.
Comment 14 Vittorio Zecca 2013-04-16 08:47:09 UTC
I still have the same bug on gfortran 4.8.0.
Comment 15 Richard Biener 2014-06-12 13:45:47 UTC
The 4.7 branch is being closed, moving target milestone to 4.8.4.
Comment 16 Jakub Jelinek 2014-12-19 13:28:53 UTC
GCC 4.8.4 has been released.
Comment 17 Richard Biener 2015-06-23 08:18:12 UTC
The gcc-4_8-branch is being closed, re-targeting regressions to 4.9.3.
Comment 18 Jakub Jelinek 2015-06-26 19:54:20 UTC
GCC 4.9.3 has been released.