Bug 44352 - ICE in string_to_single_character
Summary: ICE in string_to_single_character
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: fortran (show other bugs)
Version: 4.5.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: ice-on-valid-code
Depends on:
Blocks: Fortran_character
  Show dependency treegraph
 
Reported: 2010-05-31 16:29 UTC by Vittorio Zecca
Modified: 2011-09-11 12:04 UTC (History)
6 users (show)

See Also:
Host: x86_64-unknown-linux-gnu
Target:
Build:
Known to work: 4.6.0
Known to fail:
Last reconfirmed: 2010-06-01 07:44:41


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Vittorio Zecca 2010-05-31 16:29:02 UTC
The following provokes the summary:

      implicit real*8 (a-h,o-z)
      character*32 ddname,dname
      dname(x)=   'h810 e=0.01         '
      ddname=dname(0.d0)
          END

Best regards
Vittorio Zecca
Comment 1 Tobias Burnus 2010-06-01 07:44:41 UTC
CONFIRMED - and no regression. Thanks for the report!

test.f90:4:0: internal compiler error: in string_to_single_character, at fortran/trans-expr.c:1394

Failing assert:

string_to_single_character (tree len, tree str, int kind)
{
  gcc_assert (POINTER_TYPE_P (TREE_TYPE (str)));
Comment 2 Thomas Koenig 2010-12-03 11:29:59 UTC
The test case recurses infinitely with
-fdump-fortran-original:

Namespace: A-H: (REAL 8) I-N: (INTEGER 4) O-Z: (REAL 8)
procedure name = MAIN__
  symtree: 'MAIN__'      || symbol: 'MAIN__'
    type spec : (UNKNOWN 0)
    attributes: (PROGRAM PUBLIC  SUBROUTINE)
  symtree: 'ddname'      || symbol: 'ddname'
    type spec : (CHARACTER 32)
    attributes: (VARIABLE )
  symtree: 'dname'       || symbol: 'dname'
    type spec : (CHARACTER 32)
    attributes: (PROCEDURE STATEMENT-PROC  FUNCTION)
    value: 'h810 e=0.01         '
    result: dname
    Formal arglist: x
    Formal namespace
    Namespace: A-H: (REAL 8) I-N: (INTEGER 4) O-Z: (REAL 8)
    procedure name = MAIN__

... and so on.
Comment 3 Thomas Koenig 2010-12-03 12:23:14 UTC
Author: tkoenig
Date: Fri Dec  3 12:23:11 2010
New Revision: 167416

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=167416
Log:
2010-12-03  Thomas Koenig  <tkoenig@gcc.gnu.org>

	PR fortran/44352
	* dump-parse-tree.c (show_symbol):  Don't show formal namespace
	for statement functions in order to avoid infinite recursion.


Modified:
    trunk/gcc/fortran/ChangeLog
    trunk/gcc/fortran/dump-parse-tree.c
Comment 4 Thomas Koenig 2010-12-03 12:26:21 UTC
The infinite recursion is fixed, the original problem remains.
Comment 5 Thomas Koenig 2010-12-03 12:50:24 UTC
Reduced test case, not that there was a lot to reduce:

      character*2 ddname,dname
      dname(x)=   'x'
      ddname=dname(0.0)
          END

(the test succeeds with character*1).
Comment 6 Thomas Koenig 2010-12-03 15:55:42 UTC
This works:

      character*2 ddname,dname
      dname(x)=   'x '
      ddname=dname(0.0)
          END

We fail to pad the string for this case.
Comment 7 Thomas Koenig 2010-12-05 12:03:02 UTC
Paul, this involves (for me) some heavy voodoo regarding conversion of
strings to trees.

Do you have any idea, by any chance?
Comment 8 Paul Thomas 2010-12-07 05:39:47 UTC
(In reply to comment #7)
> Paul, this involves (for me) some heavy voodoo regarding conversion of
> strings to trees.
> 
> Do you have any idea, by any chance?

Thomas,

The odd thing is that:
      implicit real*8 (a-h,o-z)
      character*32 ddname,dname
      character*4 :: c
      dname(c) =   'h810 e=0.01         '//c
      ddname=dname("w")
      print *, ddname
          END

works, whilst removing the "//c" produces the same failure as the original.

This works too:
      implicit real*8 (a-h,o-z)
      character*32 ddname,dname
      dname(x)=   'h810 e=0.01         '//foo(x)
      ddname=dname(42.0d0)
      print *, ddname
      contains
      character*12 function foo (x)
      real*8 :: x
      write (foo, "(e12.5)") x
      end function
      END

The ICE arises because the result string is not POINTER_TYPE_P in spite of line trans-expr.c:3965
	  tmp = gfc_build_addr_expr (build_pointer_type (type), tmp);

I don't see it at all, right now :-(

Paul
Comment 9 Tobias Burnus 2010-12-07 09:45:52 UTC
(In reply to comment #8)
> The ICE arises because the result string is not POINTER_TYPE_P in spite of
> line trans-expr.c:3965
>       tmp = gfc_build_addr_expr (build_pointer_type (type), tmp);

Well, that's a different string. If one looks at the dump (with the patch) for
'h ' and a length-3 string:

    __builtin_memcpy ((void *) &dname.1, (void *) "h ", 2);
    __builtin_memset ((void *) &dname.1 + 2, 32, 1);
    __builtin_memmove ((void *) &ddname, (void *) &dname.1, 3);

Thus, one first assigns to the statement-function variable ("dname") and then memmoves the result to the LHS of the assignment ("ddname"). The ICE occured because '"h "' is not an address expression.

The following patch works. The dump also looks OK (cf. above) - though, I do not know whether it causes missed-optimization or other issues.

--- a/gcc/fortran/trans-expr.c
+++ b/gcc/fortran/trans-expr.c
@@ -1438,9 +1438,9 @@ gfc_conv_expr_op (gfc_se * se, gfc_expr * expr)
 tree
 gfc_string_to_single_character (tree len, tree str, int kind)
 {
-  gcc_assert (POINTER_TYPE_P (TREE_TYPE (str)));

-  if (!INTEGER_CST_P (len) || TREE_INT_CST_HIGH (len) != 0)
+  if (!INTEGER_CST_P (len) || TREE_INT_CST_HIGH (len) != 0
+      || !POINTER_TYPE_P (TREE_TYPE (str)))
     return NULL_TREE;

   if (TREE_INT_CST_LOW (len) == 1)
@@ -3831,7 +3831,7 @@ gfc_trans_string_copy (stmtblock_t * block, tree dlength, tree dest,
   else
     dest = gfc_build_addr_expr (pvoid_type_node, dest);

-  if (slength)
+  if (slength && POINTER_TYPE_P (TREE_TYPE (src)))
     src = fold_convert (pvoid_type_node, src);
   else
     src = gfc_build_addr_expr (pvoid_type_node, src);
Comment 10 Tobias Burnus 2010-12-07 20:29:25 UTC
Author: burnus
Date: Tue Dec  7 20:29:22 2010
New Revision: 167569

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=167569
Log:
2010-12-07  Tobias Burnus  <burnus@net-b.de>

        PR fortran/44352
        * trans-expr.c (gfc_string_to_single_character): Return if not
        POINTER_TYPE_P.
        (gfc_trans_string_copy): gfc_build_addr_expr if src or dest is
        not a pointer.
        (gfc_trans_string_copy): Make sure the argument string type
        has a string length, fix indention, and remove not needed
        gfc_build_addr_expr.

2010-12-07  Tobias Burnus  <burnus@net-b.de>

        PR fortran/44352
        * gfortran.dg/string_4.f90: New.


Added:
    trunk/gcc/testsuite/gfortran.dg/string_4.f90
Modified:
    trunk/gcc/fortran/ChangeLog
    trunk/gcc/fortran/trans-expr.c
    trunk/gcc/testsuite/ChangeLog
Comment 11 Daniel Franke 2010-12-28 17:59:25 UTC
Tobias, anything left to do here or can this report be closed?
Comment 12 Thomas Koenig 2010-12-30 17:53:02 UTC
Should this be backported to 4.5?
Comment 13 Mikael Morin 2011-02-27 22:47:33 UTC
Anything left to do here ?
Comment 14 paul.richard.thomas@gmail.com 2011-02-28 06:47:38 UTC
Dear Mikael,

It needs the backporting that Thomas suggested.  I have been away from
home for a bit and so have not had access to a 4.5 tree.  I'll be back
in 04 tomorrow night :-)

Cheers

Paul

On Sun, Feb 27, 2011 at 11:48 PM, mikael at gcc dot gnu.org
<gcc-bugzilla@gcc.gnu.org> wrote:
> http://gcc.gnu.org/bugzilla/show_bug.cgi?id=44352
>
> Mikael Morin <mikael at gcc dot gnu.org> changed:
>
>           What    |Removed                     |Added
> ----------------------------------------------------------------------------
>                 CC|                            |mikael at gcc dot gnu.org
>
> --- Comment #13 from Mikael Morin <mikael at gcc dot gnu.org> 2011-02-27 22:47:33 UTC ---
> Anything left to do here ?
>
> --
> Configure bugmail: http://gcc.gnu.org/bugzilla/userprefs.cgi?tab=email
> ------- You are receiving this mail because: -------
> You are on the CC list for the bug.
>
Comment 15 Daniel Franke 2011-07-24 18:51:30 UTC
Was this ever backported? Should it still be backported?
Comment 16 Tobias Burnus 2011-07-24 20:05:33 UTC
(In reply to comment #15)
> Was this ever backported? Should it still be backported?

No, it has only been fixed for 4.6 (and thus 4.7), but not for 4.5. It is not a regression but also existed already in 4.1. Thus, I am inclined to say no - also given that Debian stable and RHEL use 4.4 and SLES uses 4.3 such that no long-term Linux distribution uses that version.

The patch is also not obvious (though also not really complicated). Hence, I would suggest to close it as fixed. Unless, someone really wants to backport it.
Comment 17 Thomas Koenig 2011-09-11 12:04:56 UTC
In the absence of any votes for backporting, closing as FIXED.