An sh-linux targeted gcc generates: mm.i: In function ‘mmtree_RB_REMOVE_COLOR’: mm.i:36: internal compiler error: Segmentation fault Please submit a full bug report, with preprocessed source if appropriate. See for instructions. when compiling with: sh-linux-gcc -O -fomit-frame-pointer -Wall -c mm.i using the attached pre-processed source, mm.i. The toolchain is gcc-4.1.2 and binutils-2.17 (with glibc-2.3.6 headers). The host machine is a Fedora Core 4 Linux PC system. The gcc build configure line was: configure --target=sh-linux --with-headers=linux-2.4.32/include --prefix=/usr/local --with-gnu-as --with-gnu-ld --disable-libmudflap --disable-libssp --disable-shared --enable-multilib --enable-languages=c,c++ The original source of mm.i was derived when compiling the ssh v43p1 package, the original file in that package was monitor_mm.c. The attached mm.i is a preprocessed and stripped file that still reproduces the problem. Changing the optimization level stops the problem, as does not using the -momit-frame-pointer option. ---------------------------------- mm.i ------------------------------------- typedef unsigned int size_t; struct mm_share { struct { struct mm_share *rbe_left; struct mm_share *rbe_right; struct mm_share *rbe_parent; int rbe_color; } next; void *address; size_t size; }; struct mm_master { struct mmtree { struct mm_share *rbh_root; } rb_free; struct mmtree rb_allocated; void *address; size_t size; struct mm_master *mmalloc; int write; int read; }; static int mm_compare(struct mm_share *a, struct mm_share *b) { long diff = (char *)a->address - (char *)b->address; if (diff == 0) return (0); else if (diff < 0) return (-1); else return (1); } void mmtree_RB_INSERT_COLOR(struct mmtree *head, struct mm_share *elm) { struct mm_share *parent, *gparent, *tmp; while ((parent = (elm)->next.rbe_parent) && (parent)->next.rbe_color == 1) { gparent = (parent)->next.rbe_parent; if (parent == (gparent)->next.rbe_left) { tmp = (gparent)->next.rbe_right; if (tmp && (tmp)->next.rbe_color == 1) { (tmp)->next.rbe_color = 0; do { (parent)->next.rbe_color = 0; (gparent)->next.rbe_color = 1; } while (0); elm = gparent; continue; } if ((parent)->next.rbe_right == elm) { do { (tmp) = (parent)->next.rbe_right; if (((parent)->next.rbe_right = (tmp)->next.rbe_left)) { ((tmp)->next.rbe_left)->next.rbe_parent = (parent); } ; if (((tmp)->next.rbe_parent = (parent)->next.rbe_parent)) { if ((parent) == ((parent)->next.rbe_parent)->next.rbe_left) ((parent)->next.rbe_parent)->next.rbe_left = (tmp); else ((parent)->next.rbe_parent)->next.rbe_right = (tmp); } else (head)->rbh_root = (tmp); (tmp)->next.rbe_left = (parent); (parent)->next.rbe_parent = (tmp); ; if (((tmp)->next.rbe_parent)) ; } while (0); tmp = parent; parent = elm; elm = tmp; } do { (parent)->next.rbe_color = 0; (gparent)->next.rbe_color = 1; } while (0); do { (tmp) = (gparent)->next.rbe_left; if (((gparent)->next.rbe_left = (tmp)->next.rbe_right)) { ((tmp)->next.rbe_right)->next.rbe_parent = (gparent); } ; if (((tmp)->next.rbe_parent = (gparent)->next.rbe_parent)) { if ((gparent) == ((gparent)->next.rbe_parent)->next.rbe_left) ((gparent)->next.rbe_parent)->next.rbe_left = (tmp); else ((gparent)->next.rbe_parent)->next.rbe_right = (tmp); } else (head)->rbh_root = (tmp); (tmp)->next.rbe_right = (gparent); (gparent)->next.rbe_parent = (tmp); ; if (((tmp)->next.rbe_parent)) ; } while (0); } else { tmp = (gparent)->next.rbe_left; if (tmp && (tmp)->next.rbe_color == 1) { (tmp)->next.rbe_color = 0; do { (parent)->next.rbe_color = 0; (gparent)->next.rbe_color = 1; } while (0); elm = gparent; continue; } if ((parent)->next.rbe_left == elm) { do { (tmp) = (parent)->next.rbe_left; if (((parent)->next.rbe_left = (tmp)->next.rbe_right)) { ((tmp)->next.rbe_right)->next.rbe_parent = (parent); } ; if (((tmp)->next.rbe_parent = (parent)->next.rbe_parent)) { if ((parent) == ((parent)->next.rbe_parent)->next.rbe_left) ((parent)->next.rbe_parent)->next.rbe_left = (tmp); else ((parent)->next.rbe_parent)->next.rbe_right = (tmp); } else (head)->rbh_root = (tmp); (tmp)->next.rbe_right = (parent); (parent)->next.rbe_parent = (tmp); ; if (((tmp)->next.rbe_parent)) ; } while (0); tmp = parent; parent = elm; elm = tmp; } do { (parent)->next.rbe_color = 0; (gparent)->next.rbe_color = 1; } while (0); do { (tmp) = (gparent)->next.rbe_right; if (((gparent)->next.rbe_right = (tmp)->next.rbe_left)) { ((tmp)->next.rbe_left)->next.rbe_parent = (gparent); } ; if (((tmp)->next.rbe_parent = (gparent)->next.rbe_parent)) { if ((gparent) == ((gparent)->next.rbe_parent)->next.rbe_left) ((gparent)->next.rbe_parent)->next.rbe_left = (tmp); else ((gparent)->next.rbe_parent)->next.rbe_right = (tmp); } else (head)->rbh_root = (tmp); (tmp)->next.rbe_left = (gparent); (gparent)->next.rbe_parent = (tmp); ; if (((tmp)->next.rbe_parent)) ; } while (0); } } (head->rbh_root)->next.rbe_color = 0; } void mmtree_RB_REMOVE_COLOR(struct mmtree *head, struct mm_share *parent, struct mm_share *elm) { struct mm_share *tmp; while ((elm == ((void *)0) || (elm)->next.rbe_color == 0) && elm != (head)->rbh_root) { if ((parent)->next.rbe_left == elm) { tmp = (parent)->next.rbe_right; if ((tmp)->next.rbe_color == 1) { do { (tmp)->next.rbe_color = 0; (parent)->next.rbe_color = 1; } while (0); do { (tmp) = (parent)->next.rbe_right; if (((parent)->next.rbe_right = (tmp)->next.rbe_left)) { ((tmp)->next.rbe_left)->next.rbe_parent = (parent); } ; if (((tmp)->next.rbe_parent = (parent)->next.rbe_parent)) { if ((parent) == ((parent)->next.rbe_parent)->next.rbe_left) ((parent)->next.rbe_parent)->next.rbe_left = (tmp); else ((parent)->next.rbe_parent)->next.rbe_right = (tmp); } else (head)->rbh_root = (tmp); (tmp)->next.rbe_left = (parent); (parent)->next.rbe_parent = (tmp); ; if (((tmp)->next.rbe_parent)) ; } while (0); tmp = (parent)->next.rbe_right; } if (((tmp)->next.rbe_left == ((void *)0) || ((tmp)->next.rbe_left)->next.rbe_color == 0) && ((tmp)->next.rbe_right == ((void *)0) || ((tmp)->next.rbe_right)->next.rbe_color == 0)) { (tmp)->next.rbe_color = 1; elm = parent; parent = (elm)->next.rbe_parent; } else { if ((tmp)->next.rbe_right == ((void *)0) || ((tmp)->next.rbe_right)->next.rbe_color == 0) { struct mm_share *oleft; if ((oleft = (tmp)->next.rbe_left)) (oleft)->next.rbe_color = 0; (tmp)->next.rbe_color = 1; do { (oleft) = (tmp)->next.rbe_left; if (((tmp)->next.rbe_left = (oleft)->next.rbe_right)) { ((oleft)->next.rbe_right)->next.rbe_parent = (tmp); } ; if (((oleft)->next.rbe_parent = (tmp)->next.rbe_parent)) { if ((tmp) == ((tmp)->next.rbe_parent)->next.rbe_left) ((tmp)->next.rbe_parent)->next.rbe_left = (oleft); else ((tmp)->next.rbe_parent)->next.rbe_right = (oleft); } else (head)->rbh_root = (oleft); (oleft)->next.rbe_right = (tmp); (tmp)->next.rbe_parent = (oleft); ; if (((oleft)->next.rbe_parent)) ; } while (0); tmp = (parent)->next.rbe_right; } (tmp)->next.rbe_color = (parent)->next.rbe_color; (parent)->next.rbe_color = 0; if ((tmp)->next.rbe_right) ((tmp)->next.rbe_right)->next.rbe_color = 0; do { (tmp) = (parent)->next.rbe_right; if (((parent)->next.rbe_right = (tmp)->next.rbe_left)) { ((tmp)->next.rbe_left)->next.rbe_parent = (parent); } ; if (((tmp)->next.rbe_parent = (parent)->next.rbe_parent)) { if ((parent) == ((parent)->next.rbe_parent)->next.rbe_left) ((parent)->next.rbe_parent)->next.rbe_left = (tmp); else ((parent)->next.rbe_parent)->next.rbe_right = (tmp); } else (head)->rbh_root = (tmp); (tmp)->next.rbe_left = (parent); (parent)->next.rbe_parent = (tmp); ; if (((tmp)->next.rbe_parent)) ; } while (0); elm = (head)->rbh_root; break; } } else { tmp = (parent)->next.rbe_left; if ((tmp)->next.rbe_color == 1) { do { (tmp)->next.rbe_color = 0; (parent)->next.rbe_color = 1; } while (0); do { (tmp) = (parent)->next.rbe_left; if (((parent)->next.rbe_left = (tmp)->next.rbe_right)) { ((tmp)->next.rbe_right)->next.rbe_parent = (parent); } ; if (((tmp)->next.rbe_parent = (parent)->next.rbe_parent)) { if ((parent) == ((parent)->next.rbe_parent)->next.rbe_left) ((parent)->next.rbe_parent)->next.rbe_left = (tmp); else ((parent)->next.rbe_parent)->next.rbe_right = (tmp); } else (head)->rbh_root = (tmp); (tmp)->next.rbe_right = (parent); (parent)->next.rbe_parent = (tmp); ; if (((tmp)->next.rbe_parent)) ; } while (0); tmp = (parent)->next.rbe_left; } if (((tmp)->next.rbe_left == ((void *)0) || ((tmp)->next.rbe_left)->next.rbe_color == 0) && ((tmp)->next.rbe_right == ((void *)0) || ((tmp)->next.rbe_right)->next.rbe_color == 0)) { (tmp)->next.rbe_color = 1; elm = parent; parent = (elm)->next.rbe_parent; } else { if ((tmp)->next.rbe_left == ((void *)0) || ((tmp)->next.rbe_left)->next.rbe_color == 0) { struct mm_share *oright; if ((oright = (tmp)->next.rbe_right)) (oright)->next.rbe_color = 0; (tmp)->next.rbe_color = 1; do { (oright) = (tmp)->next.rbe_right; if (((tmp)->next.rbe_right = (oright)->next.rbe_left)) { ((oright)->next.rbe_left)->next.rbe_parent = (tmp); } ; if (((oright)->next.rbe_parent = (tmp)->next.rbe_parent)) { if ((tmp) == ((tmp)->next.rbe_parent)->next.rbe_left) ((tmp)->next.rbe_parent)->next.rbe_left = (oright); else ((tmp)->next.rbe_parent)->next.rbe_right = (oright); } else (head)->rbh_root = (oright); (oright)->next.rbe_left = (tmp); (tmp)->next.rbe_parent = (oright); ; if (((oright)->next.rbe_parent)) ; } while (0); tmp = (parent)->next.rbe_left; } (tmp)->next.rbe_color = (parent)->next.rbe_color; (parent)->next.rbe_color = 0; if ((tmp)->next.rbe_left) ((tmp)->next.rbe_left)->next.rbe_color = 0; do { (tmp) = (parent)->next.rbe_left; if (((parent)->next.rbe_left = (tmp)->next.rbe_right)) { ((tmp)->next.rbe_right)->next.rbe_parent = (parent); } ; if (((tmp)->next.rbe_parent = (parent)->next.rbe_parent)) { if ((parent) == ((parent)->next.rbe_parent)->next.rbe_left) ((parent)->next.rbe_parent)->next.rbe_left = (tmp); else ((parent)->next.rbe_parent)->next.rbe_right = (tmp); } else (head)->rbh_root = (tmp); (tmp)->next.rbe_right = (parent); (parent)->next.rbe_parent = (tmp); ; if (((tmp)->next.rbe_parent)) ; } while (0); elm = (head)->rbh_root; break; } } } if (elm) (elm)->next.rbe_color = 0; } struct mm_share * mmtree_RB_REMOVE(struct mmtree *head, struct mm_share *elm) { struct mm_share *child, *parent, *old = elm; int color; if ((elm)->next.rbe_left == ((void *)0)) child = (elm)->next.rbe_right; else if ((elm)->next.rbe_right == ((void *)0)) child = (elm)->next.rbe_left; else { struct mm_share *left; elm = (elm)->next.rbe_right; while ((left = (elm)->next.rbe_left)) elm = left; child = (elm)->next.rbe_right; parent = (elm)->next.rbe_parent; color = (elm)->next.rbe_color; if (child) (child)->next.rbe_parent = parent; if (parent) { if ((parent)->next.rbe_left == elm) (parent)->next.rbe_left = child; else (parent)->next.rbe_right = child; ; } else (head)->rbh_root = child; if ((elm)->next.rbe_parent == old) parent = elm; (elm)->next = (old)->next; if ((old)->next.rbe_parent) { if (((old)->next.rbe_parent)->next.rbe_left == old) ((old)->next.rbe_parent)->next.rbe_left = elm; else ((old)->next.rbe_parent)->next.rbe_right = elm; ; } else (head)->rbh_root = elm; ((old)->next.rbe_left)->next.rbe_parent = elm; if ((old)->next.rbe_right) ((old)->next.rbe_right)->next.rbe_parent = elm; if (parent) { left = parent; do { ; } while ((left = (left)->next.rbe_parent)); } goto color; } parent = (elm)->next.rbe_parent; color = (elm)->next.rbe_color; if (child) (child)->next.rbe_parent = parent; if (parent) { if ((parent)->next.rbe_left == elm) (parent)->next.rbe_left = child; else (parent)->next.rbe_right = child; ; } else (head)->rbh_root = child; color: if (color == 0) mmtree_RB_REMOVE_COLOR(head, parent, child); return (old); } struct mm_share * mmtree_RB_INSERT(struct mmtree *head, struct mm_share *elm) { struct mm_share *tmp; struct mm_share *parent = ((void *)0); int comp = 0; tmp = (head)->rbh_root; while (tmp) { parent = tmp; comp = (mm_compare)(elm, parent); if (comp < 0) tmp = (tmp)->next.rbe_left; else if (comp > 0) tmp = (tmp)->next.rbe_right; else return (tmp); } do { (elm)->next.rbe_parent = parent; (elm)->next.rbe_left = (elm)->next.rbe_right = ((void *)0); (elm)->next.rbe_color = 1; } while (0); if (parent != ((void *)0)) { if (comp < 0) (parent)->next.rbe_left = elm; else (parent)->next.rbe_right = elm; ; } else (head)->rbh_root = elm; mmtree_RB_INSERT_COLOR(head, elm); return (((void *)0)); } struct mm_share * mmtree_RB_FIND(struct mmtree *head, struct mm_share *elm) { struct mm_share *tmp = (head)->rbh_root; int comp; while (tmp) { comp = mm_compare(elm, tmp); if (comp < 0) tmp = (tmp)->next.rbe_left; else if (comp > 0) tmp = (tmp)->next.rbe_right; else return (tmp); } return (((void *)0)); } struct mm_share * mmtree_RB_NEXT(struct mmtree *head, struct mm_share *elm) { if ((elm)->next.rbe_right) { elm = (elm)->next.rbe_right; while ((elm)->next.rbe_left) elm = (elm)->next.rbe_left; } else { if ((elm)->next.rbe_parent && (elm == ((elm)->next.rbe_parent)->next.rbe_left)) elm = (elm)->next.rbe_parent; else { while ((elm)->next.rbe_parent && (elm == ((elm)->next.rbe_parent)->next.rbe_right)) elm = (elm)->next.rbe_parent; elm = (elm)->next.rbe_parent; } } return (elm); } struct mm_share * mmtree_RB_MINMAX(struct mmtree *head, int val) { struct mm_share *tmp = (head)->rbh_root; struct mm_share *parent = ((void *)0); while (tmp) { parent = tmp; if (val < 0) tmp = (tmp)->next.rbe_left; else tmp = (tmp)->next.rbe_right; } return (parent); } ------------------------------------------------------------------------------ -- Summary: internal compiler error: Segmentation fault Product: gcc Version: 4.1.2 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: gerg at snapgear dot com GCC build triplet: i686-pc-linux-gnu GCC host triplet: i686-pc-linux-gnu GCC target triplet: sh-linux http://gcc.gnu.org/bugzilla/show_bug.cgi?id=31480