This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: ICE with current mainline version
- To: Ulrich Drepper <drepper at cygnus dot com>
- Subject: Re: ICE with current mainline version
- From: Richard Henderson <rth at redhat dot com>
- Date: Tue, 21 Nov 2000 11:15:47 -0800
- Cc: gcc-patches at gcc dot gnu dot org
- References: <m3zoiv0y45.fsf@otr.mynet.cygnus.com> <20001121011437.A17829@redhat.com>
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.