This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[gfortran] Fix for constant substrings


I spotted this bug when I tried to do something which collided with this code.
 EXPR_SUBSTRING expressions have no business dealing with op1 and op2, and
this is actually done inconsistently enough to provoke a segfault in the
attached testcase.  This patch fixes this, defaulting to the correct use of
ref in all places instead. (We still don't simplify constant substring
expressions, and therefore it's still easy to construct examples which fail.)

Bubblestrapped on i686-pc-linux, the attached testcase segfaults before and
passes afterwards.  I'll commit this as obvious once testing's finished.

- Tobi

2005-02-08  Tobias Schl"uter  <tobias.schlueter@physik.uni-muenchen.de>

	* expr.c (gfc_copy_expr): Don't copy 'op1' and 'op2' for
	EXPR_SUBSTRING.
	(gfc_is_constant_expr): Check 'ref' to determine if substring
	reference is constant.
	(gfc_simplify_expr): Simplify 'ref' instead of 'op1' and 'op2'.
	(check_init_expr, check_restricted): Check 'ref' instead of 'op1'
	and 'op2'.
	* module.c (mio_expr): Read / write 'ref' instead of 'op1' and 'op2'.

Index: expr.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/fortran/expr.c,v
retrieving revision 1.20
diff -u -p -r1.20 expr.c
--- expr.c      29 Jan 2005 15:35:44 -0000      1.20
+++ expr.c      8 Feb 2005 13:21:37 -0000
@@ -393,9 +393,6 @@ gfc_copy_expr (gfc_expr * p)
       q->value.character.string = s;

       memcpy (s, p->value.character.string, p->value.character.length + 1);
-
-      q->op1 = gfc_copy_expr (p->op1);
-      q->op2 = gfc_copy_expr (p->op2);
       break;

     case EXPR_CONSTANT:
@@ -699,7 +696,8 @@ gfc_is_constant_expr (gfc_expr * e)
       break;

     case EXPR_SUBSTRING:
-      rv = gfc_is_constant_expr (e->op1) && gfc_is_constant_expr (e->op2);
+      rv = (gfc_is_constant_expr (e->ref->u.ss.start)
+           && gfc_is_constant_expr (e->ref->u.ss.end));
       break;

     case EXPR_STRUCTURE:
@@ -1115,12 +1113,10 @@ gfc_simplify_expr (gfc_expr * p, int typ
       break;

     case EXPR_SUBSTRING:
-      if (gfc_simplify_expr (p->op1, type) == FAILURE
-         || gfc_simplify_expr (p->op2, type) == FAILURE)
+      if (simplify_ref_chain (p->ref, type) == FAILURE)
        return FAILURE;

       /* TODO: evaluate constant substrings.  */
-
       break;

     case EXPR_OP:
@@ -1439,11 +1435,11 @@ check_init_expr (gfc_expr * e)
       break;

     case EXPR_SUBSTRING:
-      t = check_init_expr (e->op1);
+      t = check_init_expr (e->ref->u.ss.start);
       if (t == FAILURE)
        break;

-      t = check_init_expr (e->op2);
+      t = check_init_expr (e->ref->u.ss.end);
       if (t == SUCCESS)
        t = gfc_simplify_expr (e, 0);

@@ -1662,11 +1658,11 @@ check_restricted (gfc_expr * e)
       break;

     case EXPR_SUBSTRING:
-      t = gfc_specification_expr (e->op1);
+      t = gfc_specification_expr (e->ref->u.ss.start);
       if (t == FAILURE)
        break;

-      t = gfc_specification_expr (e->op2);
+      t = gfc_specification_expr (e->ref->u.ss.end);
       if (t == SUCCESS)
        t = gfc_simplify_expr (e, 0);

Index: module.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/fortran/module.c,v
retrieving revision 1.25
diff -u -p -r1.25 module.c
--- module.c    22 Jan 2005 18:23:40 -0000      1.25
+++ module.c    8 Feb 2005 13:21:37 -0000
@@ -2483,8 +2483,7 @@ mio_expr (gfc_expr ** ep)
     case EXPR_SUBSTRING:
       e->value.character.string = (char *)
        mio_allocated_string (e->value.character.string);
-      mio_expr (&e->op1);
-      mio_expr (&e->op2);
+      mio_ref_list (&e->ref);
       break;

     case EXPR_STRUCTURE:
! { dg-do compile }
! we used to save the wrong components of a gfc_expr describing a
! substring of a constant string.  This yielded a segfault on
! translating the expressions read from the module.
module m
  character (*), parameter :: a = "AABBCC"(1:4)
end module m

use m
character(4) :: b
b = a
end


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]