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 <URL:http://gcc.gnu.org/bugs.html> 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

Reply via email to