------- Comment #1 from pault at gcc dot gnu dot org 2009-11-12 13:50 ------- The testcase segfaults on the a = a + b and the c = c + d on Cygwin. On FC8 i386, valgrind does not show any problem with either and the testprogramme runs to completion!
However, moving a = a + b to subroutine foo and c = c+ d to subroutine bar isolates the source of the problem. bar () { { integer(kind=4) S.23; S.23 = 1; while (1) { if (S.23 > 3) goto L.11; { struct my_type D.1542; D.1542 = my_add (&c[S.23 + -1], &d[S.23 + -1]); my_assign (&c[S.23 + -1], &D.1542); } S.23 = S.23 + 1; } L.11:; } } foo () { { struct my_type D.1547; D.1547 = my_add (&a, &b); my_assign (&a, &D.1547); if (D.1547.x.data != 0B) { __builtin_free ((void *) D.1547.x.data); } D.1547.x.data = 0B; if (D.1547.y.data != 0B) { __builtin_free ((void *) D.1547.y.data); } D.1547.y.data = 0B; if (D.1547.z.data != 0B) { __builtin_free ((void *) D.1547.z.data); } D.1547.z.data = 0B; } } Most of the right allocating and freeing goes on in 'my_add' and 'my_assign'. However, whilst 'foo' (scalar) frees the allocatable components of the temporary D.1547, the same is not true for D.1542 in 'bar' (array). This loses (n = 3) x (4 bytes) x (3 components) x (dim = 10) = 360 bytes. The problem, therefore, lies in the scalarization of the elemental call to 'my_add', where the deallocation of the temporary goes walkabout. If I would hazard a guess, without looking, I would say that the post-block for the scalar assignment has not been incorporated in the loop body. Paul -- pault at gcc dot gnu dot org changed: What |Removed |Added ---------------------------------------------------------------------------- AssignedTo|unassigned at gcc dot gnu |pault at gcc dot gnu dot org |dot org | Status|UNCONFIRMED |ASSIGNED Ever Confirmed|0 |1 Last reconfirmed|0000-00-00 00:00:00 |2009-11-12 13:50:59 date| | http://gcc.gnu.org/bugzilla/show_bug.cgi?id=41936