internal compiler error
Mike Stump
mrs@wrs.com
Fri Sep 5 18:38:00 GMT 1997
> To: Robert Wilhelm <robert@physiol.med.tu-muenchen.de>
> cc: egcs-bugs@cygnus.com
> Date: Sat, 30 Aug 1997 21:54:38 -0700
> From: Jim Wilson <wilson@cygnus.com>
> This is a bug in the setjmp/longjmp exception handling support.
> The RTL emitted when sjlj exceptions is enabled is confused, and the flow
> pass is not able to determine the control flow graph. This causes the data
> flow info computed by flow to be wrong, which causes the register allocator
> to fail. We end up with an unallocated pseudo register, reload_cse_regs pass
> gets junk from out of bounds array access, and this junk value causes a
> segmentation fault when we try to dereference it.
I have developed an initial fix to try out. I would have thought that
Kenner would have flushed this code out, as he put it in and uses it
for Ada exception handling, but it appears this piece was missing, not
sure how it ever really worked without this type of patch.
I want to review it and think about it just a little longer to make
sure it is what I want, and to see if Kenner has any comments on how
it should have worked without the below patch. The fix isn't optimal,
in the sense it is fairly conservative, but it only kicks in when a
function has a setjmp, so we should be ok.
Do you (to the egcs maintainers and Kenner) see anything wrong with
it?
(Just to update you on my paperwork: I have the copyright assignment
papers signed by Wind River's VP of Engineering, but the FSF doesn't
yet have a copy; need to get it into the mail.)
* flow.c (find_basic_blocks): Make sure we know that all
CALL_INSN can get to setjmp targets, if we're using
__builtin_setjmp.
Doing diffs in .:
*** ./flow.c.~1~ Mon Aug 11 21:06:50 1997
--- ./flow.c Fri Sep 5 18:11:31 1997
*************** find_basic_blocks (f, nonlocal_label_lis
*** 560,569 ****
if (GET_CODE (insn) == CALL_INSN
&& ! find_reg_note (insn, REG_RETVAL, NULL_RTX))
{
- for (x = nonlocal_label_list; x; x = XEXP (x, 1))
- mark_label_ref (gen_rtx (LABEL_REF, VOIDmode, XEXP (x, 0)),
- insn, 0);
-
/* ??? This could be made smarter:
in some cases it's possible to tell that certain
calls will not do a nonlocal goto.
--- 560,565 ----
*************** find_basic_blocks (f, nonlocal_label_lis
*** 573,578 ****
--- 569,604 ----
only calls to those functions or to other nested
functions that use them could possibly do nonlocal
gotos. */
+
+ for (x = nonlocal_label_list; x; x = XEXP (x, 1))
+ mark_label_ref (gen_rtx (LABEL_REF, VOIDmode, XEXP (x, 0)),
+ insn, 0);
+
+ /* If we ever call setjmp, it make sure that all calls can
+ get to all setjmp targets. */
+
+ if (current_function_calls_setjmp)
+ {
+ if (label_value_list_marked_live == 0)
+ {
+ label_value_list_marked_live = 1;
+
+ /* This could be made smarter by only considering
+ these live, if the computed goto is live. */
+
+ /* Don't delete the labels (in this function) that
+ are referenced by non-jump instructions. */
+
+ for (x = label_value_list; x; x = XEXP (x, 1))
+ if (! LABEL_REF_NONLOCAL_P (x))
+ block_live[BLOCK_NUM (XEXP (x, 0))] = 1;
+ }
+
+ for (x = label_value_list; x; x = XEXP (x, 1))
+ mark_label_ref (gen_rtx (LABEL_REF, VOIDmode, XEXP (x, 0)),
+ insn, 0);
+ }
+
}
/* All blocks associated with labels in label_value_list are
--------------
cut down test case that code dumps on i686-linux without the fix, and
works with it:
// Build don't link:
// Special g++ Options: -O2
class T {
};
typedef unsigned int size_t;
inline void *operator new(size_t, void *place) throw() {
return place; }
inline void construct(T* p, const T& value) {
new (p) T(value);
}
template <class ForwardIterator>
inline void destroy(T* first, ForwardIterator last) {
for ( ; first < last; ++first)
;
}
void __uninitialized_fill_n_aux(T* first, const T& x) {
T* cur = first;
int n = 4;
try {
for ( ; n > 0; --n, ++cur)
construct(&*cur, x);
} catch(...) {
destroy(first, cur);
throw;
}
}
More information about the Gcc-bugs
mailing list