Bug with member template

Wolfram Gloger wmglo@dent.med.uni-muenchen.de
Thu Apr 9 11:23:00 GMT 1998


I am running gcc version egcs-2.90.27 980315 (egcs-1.0.2 release)
on an i586-pc-linux-gnu system.  I compiled from source using only
the patch

1997-11-06  Mike Stump  <mrs@wrs.com>

        * class.c (prepare_fresh_vtable): Enable even more complex MI
        vtable names.

which I can provide on request (but I am sure it doesn't make a
difference).

Given the appended file bug0.ii, the command
% /usr/lib/gcc-lib/i586-pc-linux-gnu/egcs-2.90.27/cc1plus bug0.ii -quiet -dumpbase bug0.cc -g -o bug0.s
gives:
granule.h: In method `short unsigned int GranuleImg::FindGranules<find_granules_image>(const struct find_granules_image &)':
granule.h:39: Internal compiler error.
granule.h:39: Please submit a full bug report to `egcs-bugs@cygnus.com'.

Omitting debug info (removing -g) makes the bug go away.

I did some research with the sources myself, and it seems that a
template instantiation is freed by the obstack mechanism, but later
used anyway, which fails because it has been overwritten by
rtx_alloc().

The place the instantiation in question is allocated is:

#0  tree_cons (purpose=0x822ed30, value=0x822eb20, chain=0x822f880)
    at ../../egcs-1.0.2/gcc/tree.c:2096
#1  0x8063dce in tsubst (t=0x82209c4, args=0x822b6ec, nargs=1, 
    in_decl=0x8221348) at ../../../egcs-1.0.2/gcc/cp/pt.c:2481
#2  0x80637fd in tsubst (t=0x8220b30, args=0x822b6ec, nargs=1, 
    in_decl=0x8221348) at ../../../egcs-1.0.2/gcc/cp/pt.c:2242
#3  0x8064e8e in tsubst_copy (t=0x8220b30, args=0x822b6ec, nargs=1, 
    in_decl=0x8221348) at ../../../egcs-1.0.2/gcc/cp/pt.c:3101
#4  0x8064b62 in tsubst_copy (t=0x8226930, args=0x822b6ec, nargs=1, 
    in_decl=0x8221348) at ../../../egcs-1.0.2/gcc/cp/pt.c:2995
#5  0x8065943 in tsubst_expr (t=0x8226930, args=0x822b6ec, nargs=1, 
    in_decl=0x8221348) at ../../../egcs-1.0.2/gcc/cp/pt.c:3419
...
#14 0x806727a in instantiate_decl (d=0x822b554)
    at ../../../egcs-1.0.2/gcc/cp/pt.c:4616

and it is referenced later via

Program received signal SIGSEGV, Segmentation fault.
0x8063922 in tsubst (t=0x82209c4, args=0x823d07c, nargs=1, in_decl=0x8220b30)
    at ../../../egcs-1.0.2/gcc/cp/pt.c:2299
../../../egcs-1.0.2/gcc/cp/pt.c:2299: No such file or directory.
(gdb) bt
#0  0x8063922 in tsubst (t=0x82209c4, args=0x823d07c, nargs=1, 
    in_decl=0x8220b30) at ../../../egcs-1.0.2/gcc/cp/pt.c:2299
#1  0x8065abf in instantiate_template (tmpl=0x8220b30, targ_ptr=0x823d07c)
    at ../../../egcs-1.0.2/gcc/cp/pt.c:3476
#2  0x804e432 in add_template_candidate (candidates=0x0, tmpl=0x8220b30, 
    explicit_targs=0x0, arglist=0x8200eb8, return_type=0x0, flags=3)
    at ../../../egcs-1.0.2/gcc/cp/call.c:4175
#3  0x8050859 in build_new_method_call (instance=0x823ce88, name=0x8220474, 
    args=0x8200ea4, basetype_path=0x0, flags=3)
    at ../../../egcs-1.0.2/gcc/cp/call.c:5725
#4  0x804ae3e in build_method_call (instance=0x823ce88, name=0x8220474, 
    parms=0x8200ea4, basetype_path=0x0, flags=3)
    at ../../../egcs-1.0.2/gcc/cp/call.c:1825
#5  0x808d404 in build_x_function_call (function=0x822f998, params=0x8200ea4, 
    decl=0x823ce88) at ../../../egcs-1.0.2/gcc/cp/typeck.c:2394
#6  0x8074681 in build_expr_from_tree (t=0x8200e38)
    at ../../../egcs-1.0.2/gcc/cp/decl2.c:3571

I noticed that tree_cons is used at gcc/tree.c:2096 where perhaps
perm_tree_cons should be used, but that is just an incompetent guess,
of course.

Regards,
Wolfram.

# 1 "bug0.cc"
 

# 1 "granule.h" 1
class GranuleImg {
public:
	typedef unsigned short index_t;
	GranuleImg(int nx_, int ny_);
	~GranuleImg();
	void    Set(int x, int y, index_t i) { mat[y][x] = i; }
	index_t Get(int x, int y) const { return mat[y][x]; }
	index_t New();

	template<class I>
	void FloodFill(const I& img, int xa, int ya, index_t i) {
		int xleft, xright;

		oldxa = xa;
		while(xa>=0 && img(xa, ya))  
			Set(xa--, ya, i);
		xleft = xa+1;
		xa = oldxa+1;
		while(xa<nx && img(xa, ya))  
			Set(xa++, ya, i);
		xright = xa;
		for(xa=xleft; xa<xright; xa++)
			if(ya>0 && img(xa, ya-1) && !Get(xa, ya-1))
				FloodFill(img, xa, ya-1, i);
		for(xa=xleft; xa<xright; xa++)
			if(ya<ny-1 && img(xa, ya+1) && !Get(xa, ya+1))
				FloodFill(img, xa, ya+1, i);
	}
	template<class I>
	index_t FindGranules(const I& img) {
		int ix, iy;
		index_t i;

		for(iy=0; iy<ny; iy++) {
			for(ix=0; ix<nx; ix++) {
				if(Get(ix, iy))
					continue;
				if(img(ix, iy) && (i = New()))
					FloodFill(img, ix, iy, i);
			}
		}
		return next_i;
	}

	long Statistics();
	int GetXMin(index_t i) { return xmin[i]; }
	long GetCount(index_t i) { return count[i]; }
private:
	int nx, ny;
	int oldxa;
	index_t next_i;  
	index_t** mat;
	int*  xmin;
	long* count;
};

 





# 3 "bug0.cc" 2


struct IMAGE {
	int nx, ny;
};

struct mask_image {
	const IMAGE* img;
	mask_image(const IMAGE* img_): img(img_) {}
	int operator()(int ix, int iy) const {
		return 1;
	}
};

void
t0(IMAGE* img)
{
	GranuleImg g(img->nx, img->ny);
	mask_image mimg(img);
	g.FindGranules(mimg);
}

struct Image {
	int GetNX();
	int GetNY();
	int GetImgPoint(int ix, int iy) const;
	void FindGranules();
};

struct find_granules_image {
	const Image& img;
	find_granules_image(const Image& img_): img(img_) {}
	int operator()(int ix, int iy) const {
		return !img.GetImgPoint(ix, iy);
	}
};

void
Image::FindGranules()
{
	GranuleImg g(GetNX(), GetNY());
	find_granules_image img(*this);
	g.FindGranules(img);
}

 






-- 
`Surf the sea, not double-u three...'
wmglo@dent.med.uni-muenchen.de



More information about the Gcc-bugs mailing list