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]

Re: ICE with current mainline version


On Tue, Nov 21, 2000 at 01:14:37AM -0800, Richard Henderson wrote:
> On Mon, Nov 20, 2000 at 01:52:10AM -0800, Ulrich Drepper wrote:
> > dcigettext.c: In function `__dcigettext':
> > dcigettext.c:503: warning: unreachable code at beginning of switch statement
> > dcigettext.c:655: Internal error: Speicherzugriffsfehler.
> 
> Here is a cut down test case, committed as compile/20001121-1.c.

SAVE_EXPR uses an RTL_EXPR, which is unsafe for re-evaluation during
call argument expansion.  The tricky part is that the RTL_EXPR is
not created until the SAVE_EXPR is expanded for the first time, so
the tree walk currently employed will not notice the danger.

So we must add a hook for the front end to process its own tree codes.



r~


        * c-common.c (c_unsafe_for_reeval): New function.
        (add_c_tree_codes): Register it.
        * c-common.h: Declare it.
        * tree.c (lang_unsafe_for_reeval): New hook.
        (unsafe_for_reeval): Call it.
        * tree.h: Declare it.

Index: c-common.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/c-common.c,v
retrieving revision 1.190
diff -c -p -d -r1.190 c-common.c
*** c-common.c	2000/11/17 06:05:12	1.190
--- c-common.c	2000/11/21 19:03:38
*************** c_safe_from_p (target, exp)
*** 5924,5929 ****
--- 5924,5943 ----
    return 1;
  }
  
+ /* Hook used by unsafe_for_reeval to handle language-specific tree codes.  */
+ 
+ int
+ c_unsafe_for_reeval (exp)
+      tree exp;
+ {
+   /* Statement expressions may not be reevaluated.  */
+   if (TREE_CODE (exp) == STMT_EXPR)
+     return 2;
+ 
+   /* Walk all other expressions.  */
+   return -1;
+ }
+ 
  /* Tree code classes. */
  
  #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) TYPE,
*************** add_c_tree_codes ()
*** 5971,5976 ****
--- 5985,5991 ----
    memcpy (tree_code_name + (int) LAST_AND_UNUSED_TREE_CODE,
  	  c_tree_code_name,
  	  (LAST_C_TREE_CODE - (int)LAST_AND_UNUSED_TREE_CODE) * sizeof (char *));
+   lang_unsafe_for_reeval = c_unsafe_for_reeval;
  }
  
  #define CALLED_AS_BUILT_IN(NODE) \
Index: c-common.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/c-common.h,v
retrieving revision 1.49
diff -c -p -d -r1.49 c-common.h
*** c-common.h	2000/11/14 10:38:01	1.49
--- c-common.h	2000/11/21 19:03:38
*************** extern struct rtx_def *c_expand_expr    
*** 757,764 ****
  							 enum expand_modifier));
  
  extern int c_safe_from_p                        PARAMS ((rtx, tree));
- 
  #endif
  
  /* In dump.c */
  
--- 757,765 ----
  							 enum expand_modifier));
  
  extern int c_safe_from_p                        PARAMS ((rtx, tree));
  #endif
+ 
+ extern int c_unsafe_for_reeval			PARAMS ((tree));
  
  /* In dump.c */
  
Index: tree.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/tree.c,v
retrieving revision 1.175
diff -c -p -d -r1.175 tree.c
*** tree.c	2000/11/19 23:40:36	1.175
--- tree.c	2000/11/21 19:03:38
*************** static void finish_vector_type PARAMS((t
*** 179,184 ****
--- 179,187 ----
  void (*lang_unsave) PARAMS ((tree *));
  void (*lang_unsave_expr_now) PARAMS ((tree));
  
+ /* If non-null, these are language-specific helper functions for
+    unsafe_for_reeval.  Return negative to not handle some tree.  */
+ int (*lang_unsafe_for_reeval) PARAMS ((tree));
  
  tree global_trees[TI_MAX];
  tree integer_types[itk_none];
*************** unsafe_for_reeval (expr)
*** 1778,1784 ****
        break;
  
      default:
!       /* ??? Add a lang hook if it becomes necessary.  */
        break;
      }
  
--- 1781,1792 ----
        break;
  
      default:
!       if (lang_unsafe_for_reeval != 0)
! 	{
! 	  tmp = (*lang_unsafe_for_reeval) (expr);
! 	  if (tmp >= 0)
! 	    return tmp;
! 	}
        break;
      }
  
Index: tree.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/tree.h,v
retrieving revision 1.212
diff -c -p -d -r1.212 tree.h
*** tree.h	2000/11/17 17:31:08	1.212
--- tree.h	2000/11/21 19:03:38
*************** extern void (*lang_unsave_expr_now)     
*** 2255,2261 ****
  /* Return 0 if it is safe to evaluate EXPR multiple times,
     return 1 if it is safe if EXPR is unsaved afterward, or
     return 2 if it is completely unsafe.  */
! extern int unsafe_for_reeval PARAMS ((tree));
  
  /* Return 1 if EXP contains a PLACEHOLDER_EXPR; i.e., if it represents a size
     or offset that depends on a field within a record.
--- 2255,2265 ----
  /* Return 0 if it is safe to evaluate EXPR multiple times,
     return 1 if it is safe if EXPR is unsaved afterward, or
     return 2 if it is completely unsafe.  */
! extern int unsafe_for_reeval		PARAMS ((tree));
! 
! /* If non-null, these are language-specific helper functions for
!    unsafe_for_reeval.  Return negative to not handle some tree.  */
! extern int (*lang_unsafe_for_reeval)	PARAMS ((tree));
  
  /* Return 1 if EXP contains a PLACEHOLDER_EXPR; i.e., if it represents a size
     or offset that depends on a field within a record.

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