Article View: gnu.g++.bug
Article #1186compiler goes recursive, eats up all stack space, then quits
From: dap
Date: Tue, 29 Dec 1992 07:46
Date: Tue, 29 Dec 1992 07:46
352 lines
13437 bytes
13437 bytes
Using gcc 2.3.2 on a BSDI system, attempting to compile the
uunet:networking/leffler/v2.0beta22*.Z(util/Path.c++) file.
This is an extraction of the salient portions thereof.
Please note that this bug report is copyrighted, and preserve the copyright
notices :-)
=-= bug.list =-=
cd /u/dap/
/usr/local/bin/g++ -v -D__ANSI_CPP__ bug.cc
Reading specs from /usr/local/lib/gcc-lib/i386-bsdi/2.3.2/specs
gcc version 2.3.2
/usr/local/lib/gcc-lib/i386-bsdi/2.3.2/cpp -lang-c++ -v -undef -D__GNUC__=2 -D__GNUG__=2 -D__cplusplus -Dunix -Di386 -D__bsdi__ -Dbsdi -DBSD_NET2 -D__unix__ -D__i386__ -D__bsdi__ -D__bsdi__ -D__BSD_NET2__ -D__unix -D__i386 -D__bsdi__ -D__bsdi -D__BSD_NET2 -D__ANSI_CPP__ bug.cc /var/tmp/cc009208.i
GNU CPP version 2.3.2 (80386, BSD syntax)
/usr/local/lib/gcc-lib/i386-bsdi/2.3.2/cc1plus /var/tmp/cc009208.i -quiet -dumpbase bug.cc -version -o /var/tmp/cc009208.s
GNU C++ version 2.3.2 (80386, BSD syntax) compiled by GNU C version 2.3.2.
bug.cc:29: undefined or invalid # directive
bug.cc: In method `void fxObj::dec ()':
bug.cc:55: warning: implicit declaration of function `fxAssert'
bug.cc: In method `fxTempStr::operator int ()const ':
bug.cc:102: warning: implicit declaration of function `atoi'
bug.cc: In method `fxTempStr::operator float ()const ':
bug.cc:103: warning: implicit declaration of function `atof'
bug.cc: In method `int Path::findFile (const class fxStr&, class fxStr&)':
bug.cc:292: warning: implicit declaration of function `access'
bug.cc:300: virtual memory exhausted
Compilation exited abnormally with code 1 at Tue Dec 29 12:40:48
=-= bug.cc =-=
/*
* Copyright (c) 1990, 1991, 1992 Sam Leffler
* Copyright (c) 1991, 1992 Silicon Graphics, Inc.
*
* Permission to use, copy, modify, distribute, and sell this software and
* its documentation for any purpose is hereby granted without fee, provided
* that (i) the above copyright notices and this permission notice appear in
* all copies of the software and related documentation, and (ii) the names of
* Sam Leffler and Silicon Graphics may not be used in any advertising or
* publicity relating to the software without the specific, prior written
* permission of Sam Leffler and Silicon Graphics.
*
* THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
* EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
* WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
*
* IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
* ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
* OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
* WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
* LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
* OF THIS SOFTWARE.
*/
typedef unsigned fxBool;
#define FALSE 0
#define TRUE 1
#incclude <stdlib>
#include <sys/types.h>
// Reference counted objects. Subclasses of this can use Ptr's.
class fxObj {
public:
fxObj();
virtual ~fxObj();
// Memory management
void inc();
void dec();
u_long getReferenceCount();
// Misc
virtual const char* className() const;
int compare(const fxObj *) const;
virtual void subClassMustDefine(const char* method) const;
protected:
u_long referenceCount;
};
inline fxObj::fxObj() { referenceCount = 0; }
inline fxObj::~fxObj() { }
inline void fxObj::inc() { ++referenceCount; }
inline void fxObj::dec() {
fxAssert(referenceCount>0,"Bogus object reference count");
if (0 >= --referenceCount) delete this;
}
inline u_long fxObj::getReferenceCount() { return referenceCount; }
// Temporary strings are generated by the concatenation operators.
// They are designed to avoid calls to malloc, and as such are not
// meant to be used directly.
class fxStr;
class fxTempStr {
public:
fxTempStr(fxTempStr const &other);
~fxTempStr();
// C++ uses these operators to perform the first concatenation
friend fxTempStr operator|(fxStr const&, fxStr const&);
friend fxTempStr operator|(fxStr const&, char const*);
friend fxTempStr operator|(char const*, fxStr const&);
// Susequent concatenations use these operators. These operators
// just append the argument data to the temporary, avoiding malloc
// when possible.
// XXX these aren't really const, although they are declared as such
// XXX to avoid warnings. In a land of very advanced compilers, this
// XXX strategy may backfire.
friend fxTempStr& operator|(const fxTempStr&, fxStr const& b);
friend fxTempStr& operator|(const fxTempStr&, char const* b);
operator char*() const;
operator int() const;
operator float() const;
operator double() const;
u_int length() const;
protected:
char indata[100]; // inline data, avoiding malloc
char* data; // points at indata or heap
u_int slength; // same rules as fxStr::slength
friend class fxStr;
fxTempStr(char const *, u_int, char const *, u_int);
fxTempStr& concat(char const* b, u_int bl);
};
inline fxTempStr::operator char*() const { return data; }
inline fxTempStr::operator int() const { return atoi(data); }
inline fxTempStr::operator float() const { return float(atof(data)); }
inline fxTempStr::operator double() const { return double(atof(data)); }
inline u_int fxTempStr::length() const { return slength - 1; }
//----------------------------------------------------------------------
class fxStr {
friend class fxTempStr;
public:
fxStr(u_int l=0);
fxStr(char const *s);
fxStr(char const *s, u_int len);
fxStr(fxStr const&);
fxStr(int, char const* format);
fxStr(float, char const* format);
fxStr(double, char const* format);
fxStr(const fxTempStr&);
~fxStr();
/////////////////////////////////////////////////////
u_long hash() const;
operator char*() const
{ return data; }
operator int() const
{ return atoi(data); }
operator float() const
{ return float(atof(data)); }
operator double() const
{ return double(atof(data)); }
u_int length() const { return slength-1; }
char& operator[](u_int i) const
{ fxAssert(i<slength-1,"Invalid Str[] index");
return data[i]; }
void operator=(const fxTempStr& s);
void operator=(fxStr const& s);
void operator=(char const *s);
/////////////////////////////////////////////////////
// Comparison
friend fxBool operator==(fxStr const&, fxStr const&);
friend fxBool operator==(fxStr const&, char const*);
friend fxBool operator==(char const*, fxStr const&);
friend fxBool operator!=(fxStr const&, fxStr const&);
friend fxBool operator!=(fxStr const&, char const*);
friend fxBool operator!=(char const*, fxStr const&);
friend fxBool operator>=(fxStr const&, fxStr const&);
friend fxBool operator>=(fxStr const&, char const*);
friend fxBool operator>=(char const*, fxStr const&);
friend fxBool operator<=(fxStr const&, fxStr const&);
friend fxBool operator<=(fxStr const&, char const*);
friend fxBool operator<=(char const*, fxStr const&);
friend fxBool operator>(fxStr const&, fxStr const&);
friend fxBool operator>(fxStr const&, char const*);
friend fxBool operator>(char const*, fxStr const&);
friend fxBool operator<(fxStr const&, fxStr const&);
friend fxBool operator<(fxStr const&, char const*);
friend fxBool operator<(char const*, fxStr const&);
int compare(fxStr const *a) const { return ::compare(*this, *a); }
friend int compare(fxStr const&, fxStr const&);
friend int compare(fxStr const&, char const*);
friend int compare(char const*, fxStr const&);
/////////////////////////////////////////////////////
// Concatenation
friend fxTempStr& operator|(const fxTempStr&, fxStr const&);
friend fxTempStr& operator|(const fxTempStr&, char const*);
friend fxTempStr operator|(fxStr const&, fxStr const&);
friend fxTempStr operator|(fxStr const&, char const*);
friend fxTempStr operator|(char const*, fxStr const&);
/////////////////////////////////////////////////////
// Misc
fxStr copy() const;
fxStr extract(u_int start,u_int len) const;
fxStr cut(u_int start,u_int len);
fxStr head(u_int) const;
fxStr tail(u_int) const;
void lower();
void raise();
void remove(u_int posn,u_int len=1);
void resize(u_int len, fxBool reallocate = FALSE);
void setMaxLength(u_int maxlen);
void append(char a);
void append(char const *s, u_int len=0);
void append(const fxTempStr& s)
{ append((char*)s, s.slength-1); }
void append(fxStr const& s)
{ append((char*)s, s.slength-1); }
void insert(char a, u_int posn=0);
void insert(char const *, u_int posn=0, u_int len=0);
void insert(const fxTempStr& s, u_int posn=0)
{ insert((char*)s, posn, s.slength-1); }
void insert(fxStr const& s, u_int posn=0)
{ insert((char*)s, posn, s.slength-1); }
/////////////////////////////////////////////////////
// Parsing
u_int next(u_int posn, char delimiter) const;
u_int next(u_int posn, char const *delimiters, u_int len=0) const;
u_int next(u_int posn, fxStr const& delimiters) const
{ return next(posn, (char*)delimiters, delimiters.slength-1); }
u_int nextR(u_int posn, char delimiter) const;
u_int nextR(u_int posn, char const*, u_int len=0) const;
u_int nextR(u_int posn, fxStr const& delimiters) const
{ return nextR(posn, (char*)delimiters, delimiters.slength-1); }
u_int skip(u_int posn, char a) const;
u_int skip(u_int posn, char const *, u_int len=0) const;
u_int skip(u_int posn, fxStr const& delimiters) const
{ return skip(posn, (char*)delimiters, delimiters.slength-1); }
u_int skipR(u_int posn, char a) const;
u_int skipR(u_int posn, char const *, u_int len=0) const;
u_int skipR(u_int posn, fxStr const& delimiters) const
{ return skipR(posn, (char*)delimiters, delimiters.slength-1); }
fxStr token(u_int & posn, char delimiter) const;
fxStr token(u_int & posn, char const * delimiters,
u_int delimiters_len = 0) const;
fxStr token(u_int & posn, fxStr const & delimiters) const
{ return token(posn, delimiters.data, delimiters.slength-1); }
fxStr tokenR(u_int & posn, char delimiter) const;
fxStr tokenR(u_int & posn, char const * delimiters,
u_int delimiters_len = 0) const;
fxStr tokenR(u_int & posn, fxStr const & delimiters) const
{ return tokenR(posn, delimiters.data, delimiters.slength-1); }
protected:
// slength is one greater than the true length of the data.
// This is because the data is null-terminated. However, the
// data may contain nulls; they will be ignored. This is to
// provide compatibility with ordinary C-style strings, and
// with arbitrary data. slength is always positive.
u_int slength;
// data points to the actual data. It is always a valid pointer.
char * data;
// zero-length string support
// resizeInternal doesn't update slength or handle null termination
static char emptyString;
void fxStr::resizeInternal(u_int);
int findEndBuffer(const char *, u_int buflen) const;
int findBuffer(const char *buf, u_int buflen) const;
void bracketBuffer(const char *, u_int buflen, int &, int &) const;
};
class Path : public fxStr {
protected:
char sep;
friend class PathIterator;
public:
Path(const char *envVar, char *defPath, const char separator = ':');
virtual ~Path();
// search for file name and return pathname in result
virtual findFile(const fxStr& name, fxStr& result);
};
class PathIterator {
protected:
Path& path;
short off;
public:
PathIterator(Path& p) : path(p) { off = 0; }
notDone() { return (off < path.slength); }
void operator++();
operator fxStr();
};
Path::findFile(const fxStr& name, fxStr& result)
{
if (name[0] == '/' && access((char*) name, 0) == 0) {
result = name;
return (1);
}
for (PathIterator it(*this); it.notDone(); it++) {
#ifdef __bsdi__
//
// Note: the bug is evident if __bsdi__ or not __bsdi__. I was mucking
// around here trying to figure out a workaround, but gave up.
//
// However, the compiler will coredump on the following if it manages
// to get past the ``gxx_bug = it''.
//
fxStr gxx_bug;
gxx_bug = it; // compiler goes infinite here
gxx_bug |= "/"; // then, after an infinite amount of time&space,
// dumps core here. (fast CPUs are wonderful)
gxx_bug |= name;
char* pathname = gxx_bug;
#else
char* pathname = it | "/" | name;
#endif
if (access(pathname, 0) == 0) {
result = pathname;
return 1;
}
}
return 0;
}
Technical Details
Message-ID:
<9212291946.AA06956@fubar>Path:
arc1-ca.pugleaf.net!sparky!uunet!cis.ohio-state.edu!fubar.UUCP!dapShow Full Headers
Complete Article Headers
Newsgroups: gnu.g++.bug Path: arc1-ca.pugleaf.net!sparky!uunet!cis.ohio-state.edu!fubar.UUCP!dap From: dap@fubar.UUCP Subject: compiler goes recursive, eats up all stack space, then quits Message-ID: <9212291946.AA06956@fubar> Sender: gnulists@ai.mit.edu Organization: GNUs Not Usenet Distribution: gnu Date: Tue, 29 Dec 1992 07:46:46 GMT Approved: bug-g++@prep.ai.mit.edu Lines: 355