[gnu.g++.bug] BUG in G++ 1.35.0

rfg@MCC.COM (Ron Guilmette) (04/23/89)

As the following source file demonstrates, G++ 1.35.0 (pre-release Sun3)
allows you to declare formal arguments to be of type "void&".
According to "The Book" (page 270) this should not be legal.

b038 had missed error(s) as follows:
	8: void test2 (void& formal_void_ref)		// ERROR
b038: FAILED
----------------------------------------------------------------------------
// Check that it is illegal to declare a reference-to-void
// type object.

const void* null = 0;

void& global_void_ref = *null;			// ERROR

void test2 (void& formal_void_ref)		// ERROR
{
	void& local_void_ref = formal_void_ref;	// ERROR
}

void test ()
{
	void& local_void_ref = *null;		// ERROR

	test2 (local_void_ref);
}
-----------------------------------------------------------------------------
/usr/local/src/src/g++/build/sun3/1.35-.0-.0/g++ -B/usr/local/src/src/g++/build/sun3/1.35-.0-.0/ -ansi -pedantic -Wall -Wwrite-strings -S -v b038.C
g++ version 1.35.0-
 /usr/local/src/src/g++/build/sun3/1.35-.0-.0/cpp -+ -v -undef -D__GNU__ -D__GNUG__ -T -D__STRICT_ANSI__ -D__mc68000__ -D__sun__ -D__unix__ -pedantic -Wall -D__HAVE_68881__ b038.C /tmp/cca17992.cpp
GNU CPP version 1.35.0-
 /usr/local/src/src/g++/build/sun3/1.35-.0-.0/c++ /tmp/cca17992.cpp -quiet -dumpbase b038.C -Wall -Wwrite-strings -pedantic -ansi -noreg -version -o b038.s
GNU C++ version 1.35.0- (68k, MIT syntax) compiled by GNU C version 1.34.1.
b038.C:6: invalid type: `void &'
b038.C:6: variable or field `global_void_ref' declared void
b038.C:6: invalid use of void expression
b038.C:9: invalid type: `void &'
In function void test2 ():
b038.C:10: invalid type: `void &'
b038.C:10: variable or field `local_void_ref' declared void
b038.C:10: `formal_void_ref' was not declared (first use this function)
b038.C:10: (Each undeclared identifier is reported only once
b038.C:10: for each function it appears in.)
b038.C:10: warning: unused variable `local_void_ref'
In function void test ():
b038.C:15: invalid type: `void &'
b038.C:15: variable or field `local_void_ref' declared void
b038.C:15: invalid use of void expression
b038.C:9: too many arguments to function `void test2 ()'
b038.C:17: at this point in file

rfg@MCC.COM (Ron Guilmette) (04/23/89)

It appears that if you use the -ansi options with g++, which may
sometimes be needed to get certain ANSI features, the use of this
options disables a very critical and *STANDARD* feature of C++,
i.e. the "inline" keyword.


This action makes sense for GCC, but not for G++.  I suggest that
"inline" retain its usual (and legal) meaning even when -ansi is
being used with g++.

// rfg

rfg@MCC.COM (Ron Guilmette) (04/28/89)

The following file fails compilation when using G++ 1.35.0- on a Sun3.
This same file passes compilation (without errors or warnings) when
using g++ 1.34.1.  I believe that it is legal code and should pass.

-------------------------------------------------------------------------
// Check that if explicit conversion (to a base type) is used,
// the compiler can still find a proper (implicitly generated)
// initialization member function to apply to the converted value.

struct base {
	int base_member;

	base () {}
	//base (const base& br) { *this = br; }		// This makes it work.
};

struct derived : public base {
	int derived_member;
};

base base_object;

int main ()
{
	derived derived_object;

	base_object = (base) derived_object;
	return 0;
}
-------------------------------------------------------------------------
/usr/local/src/src/g++/build/sun3/1.35-.0-.0/g++ -B/usr/local/src/src/g++/build/sun3/1.35-.0-.0/ -Wall -Wwrite-strings -ansi -pedantic -S -v a026.C
In function int main ():
a026.C:22: too many arguments to function

// Ron Guilmette  -  MCC  -  Experimental Systems Kit Project
// 3500 West Balcones Center Drive,  Austin, TX  78759  -  (512)338-3740
// ARPA: rfg@mcc.com
// UUCP: {rutgers,uunet,gatech,ames,pyramid}!cs.utexas.edu!pp!rfg

rfg@MCC.COM (Ron Guilmette) (04/29/89)

When compiled with G++ 1.35.0-/Sun3, the following source file causes
the compiler to SEGFAULT.

----------------------------------------------------------------------
// Check that if a function is declared as inline that subsequent
// declarations/definitions must also be declared inline.

inline void function_1 ();

void function_1 ();			// ERROR

inline void function_2 ();

void function_2 ()			// ERROR
{
}

struct base {
	inline void member_1 ();

	void member_1 ();		// ERROR

	inline void member_2 ();

	void member_2 ()		// ERROR
	{}

	inline void member_3 ();
	inline void member_4 ();
};

void base::member_3 ();			// ERROR

void base::member_3 ()			// possible error
{
}

void base::member_4 ()			// ERROR
{
}
-----------------------------------------------------------------------
/usr/local/src/src/g++/build/sun3/1.35-.0-.0/g++ -B/usr/local/src/src/g++/build/sun3/1.35-.0-.0/ -ansi -pedantic -Wall -Wwrite-strings -S -v b042.C
g++ version 1.35.0-.0
 /usr/local/src/src/g++/build/sun3/1.35-.0-.0/cpp -+ -v -undef -D__GNU__ -D__GNUG__ -T -D__STRICT_ANSI__ -D__mc68000__ -D__sun__ -D__unix__ -pedantic -Wall -D__HAVE_68881__ b042.C /tmp/cca07041.cpp
GNU CPP version 1.35.0-.0
 /usr/local/src/src/g++/build/sun3/1.35-.0-.0/c++ /tmp/cca07041.cpp -quiet -dumpbase b042.C -Wall -Wwrite-strings -pedantic -ansi -noreg -version -o b042.s
/usr/local/src/src/g++/build/sun3/1.35-.0-.0/g++: Program c++ got fatal signal 11.

// Ron Guilmette  -  MCC  -  Experimental Systems Kit Project
// 3500 West Balcones Center Drive,  Austin, TX  78759  -  (512)338-3740
// ARPA: rfg@mcc.com
// UUCP: {rutgers,uunet,gatech,ames,pyramid}!cs.utexas.edu!pp!rfg

rfg@MCC.COM (Ron Guilmette) (04/29/89)

(This error is different from the last one!)

G++ 1.35.0-/Sun3 SEGFAULTS when compiling the following source file.

----------------------------------------------------------------------
// Check that if a function is declared as non-inline that subsequent
// declarations/definitions must also be declared as non-inline.

void function_1 ();

inline void function_1 ();		// ERROR

void function_2 ();

inline void function_2 ()		// ERROR
{
}

struct base {
	void member_1 ();

	inline void member_1 ();	// ERROR

	void member_2 ();

	inline void member_2 ()		// ERROR
	{}

	void member_3 ();
	void member_4 ();
};

inline void base::member_3 ();		// ERROR

inline void base::member_3 ()		// possible error
{
}

inline void base::member_4 ()		// ERROR
{
}
------------------------------------------------------------------------
/usr/local/src/src/g++/build/sun3/1.35-.0-.0/g++ -B/usr/local/src/src/g++/build/sun3/1.35-.0-.0/ -ansi -pedantic -Wall -Wwrite-strings -S -v b043.C
g++ version 1.35.0-.0
 /usr/local/src/src/g++/build/sun3/1.35-.0-.0/cpp -+ -v -undef -D__GNU__ -D__GNUG__ -T -D__STRICT_ANSI__ -D__mc68000__ -D__sun__ -D__unix__ -pedantic -Wall -D__HAVE_68881__ b043.C /tmp/cca07118.cpp
GNU CPP version 1.35.0-.0
 /usr/local/src/src/g++/build/sun3/1.35-.0-.0/c++ /tmp/cca07118.cpp -quiet -dumpbase b043.C -Wall -Wwrite-strings -pedantic -ansi -noreg -version -o b043.s
/usr/local/src/src/g++/build/sun3/1.35-.0-.0/g++: Program c++ got fatal signal 11.

// Ron Guilmette  -  MCC  -  Experimental Systems Kit Project
// 3500 West Balcones Center Drive,  Austin, TX  78759  -  (512)338-3740
// ARPA: rfg@mcc.com
// UUCP: {rutgers,uunet,gatech,ames,pyramid}!cs.utexas.edu!pp!rfg

rfg@MCC.COM (Ron Guilmette) (04/29/89)

b046 had missed error(s) as follows:
	14: 	test_1 ();			// ERROR
	15: 	base_object.member ();		// ERROR
b046: FAILED


---------------------------------------------------------------------
// Check that an inline function must be defined before it
// is called.

inline void test_1 ();

struct base {
	inline void member ();
};

base base_object;

void test_2 ()
{
	test_1 ();			// ERROR
	base_object.member ();		// ERROR
}

inline void test_1 ()
{
}

inline void base::member ()
{
}
------------------------------------------------------------------------
/usr/local/src/src/g++/build/sun3/1.35-.0-.0/g++ -B/usr/local/src/src/g++/build/sun3/1.35-.0-.0/ -Wall -Wwrite-strings -S -v b046.C
g++ version 1.35.0-.0
 /usr/local/src/src/g++/build/sun3/1.35-.0-.0/cpp -+ -v -undef -D__GNU__ -D__GNUG__ -Dmc68000 -Dsun -Dunix -D__mc68000__ -D__sun__ -D__unix__ -Wall -D__HAVE_68881__ -Dmc68020 b046.C /tmp/cca07559.cpp
GNU CPP version 1.35.0-.0
 /usr/local/src/src/g++/build/sun3/1.35-.0-.0/c++ /tmp/cca07559.cpp -quiet -dumpbase b046.C -Wall -Wwrite-strings -noreg -version -o b046.s
GNU C++ version 1.35.0-.0 (68k, MIT syntax) compiled by GNU C version 1.34.1.

rfg@MCC.COM (Ron Guilmette) (05/03/89)

As the following short program demonstrates, G++ 1.35.0- breaks
the semantics of the method-call operator ->()() in that it causes
the method call operator to be invoked *even* when it didn't use to
be, i.e. when you are calling a member function of the current
class from within another member function of the current class.

The following patch seems to fix the problem, but I am not at all sure
that this is the "correct" solution.  It just seems to work.

diff -rc2 1.35-.0--/cplus-class.c 1.35-.0-+/cplus-class.c
*** 1.35-.0--/cplus-class.c	Wed Apr 19 00:45:12 1989
--- 1.35-.0-+/cplus-class.c	Tue May  2 17:31:14 1989
***************
*** 3454,3458 ****
  	       || strncmp (IDENTIFIER_POINTER (DECL_NAME (function)),
  			   "op$method_call", 13))
! 	   && (may_be_remote (basetype) || instance != C_C_D))
      {
        register int used, size;
--- 3454,3458 ----
  	       || strncmp (IDENTIFIER_POINTER (DECL_NAME (function)),
  			   "op$method_call", 13))
! 	   && (may_be_remote (basetype) || (C_C_D ? (TREE_TYPE (instance) != TREE_TYPE(C_C_D)) : 1 )))
      {
        register int used, size;

---------------------------------------------------------------------------------
typedef int MP;

class base;

typedef void (base::*base_method_ptr) ();

class base {
	int member;
public:
	base () {}
	base operator ->() (MP method_id, int arg_bytes, ...)
	{
		base_method_ptr bmp = (base_method_ptr) method_id;

		printf ("operator->()() called\n");
		(this->*(bmp)) ();
	}
};

class derived : public base {
	int member;
public:
	derived () {}
	void method_1 ()
	{
		printf ("method_1() called\n");
	}
	void method_2 ()
	{
		printf ("method_2() called\n");
		method_1 ();
	}
};

int main ()
{
	derived derived_object;

	derived_object.method_2 ();
}
---------------------------------------------------------------------------------


// Ron Guilmette  -  MCC  -  Experimental Systems Kit Project
// 3500 West Balcones Center Drive,  Austin, TX  78759  -  (512)338-3740
// ARPA: rfg@mcc.com
// UUCP: {rutgers,uunet,gatech,ames,pyramid}!cs.utexas.edu!pp!rfg

rfg@MCC.COM (Ron Guilmette) (05/05/89)

The following program incorrectly returns a non-zero exit status because
a new call to "base_returning_function" is generated for each usage of
the reference constant "base_ref".

-------------------------------------------------------------------------
// Check that if a reference is initialized to refer to a value
// which is returned from a function call, the actual call to
// the function is only invoked for the original initialization
// of the reference, and not for each subsequent use of the
// reference.
//
// This test fails with G++ 1.35.0- (pre-release).
// Reported 4/4/89 by Kim Smith

struct base {
	int data_member;

	void function_member ();
};

base base_object;

base base_returning_function ();

int call_count = 0;

int main ()
{
	base& base_ref = base_returning_function ();

	base_ref.function_member ();
	base_ref.function_member ();
	base_ref.data_member  = 99;
	return (call_count == 1) ? 0 : 1;
}

base base_returning_function ()
{
	base local_base_object;

	call_count++;
	return local_base_object;
}

void base::function_member ()
{
}

rfg@MCC.COM (Ron Guilmette) (05/11/89)

The following program causes g++ 1.35.0- to issue invalid error
messages (shown below).

------------------------------------------------------------------
// Check that enum types can be declared within structs.
//
// Bug found by Wayne Allen 4/10/89 in g++ 1.34.1.1

struct s {
	int member;
	enum color { red, orange, yellow };
	color c;
};

int main ()
{
	return 0;
}
------------------------------------------------------------------
g++-new-new -g -Wall -Wwrite-strings -v -S a032.C
g++ version 1.35.0-.0
 /usr/local/src/lib/sun3/g++-1.35.0-.0/gcc-cpp -+ -v -undef -D__GNU__ -D__GNUG__ -Dmc68000 -Dsun -Dunix -D__mc68000__ -D__sun__ -D__unix__ -Wall -D__HAVE_68881__ -Dmc68020 a032.C /tmp/cca18087.cpp
GNU CPP version 1.35.0-.0
 /usr/local/src/lib/sun3/g++-1.35.0-.0/gcc-cc1plus /tmp/cca18087.cpp -quiet -dumpbase a032.C -Wall -Wwrite-strings -noreg -version -G -o a032.s
GNU C++ version 1.35.0-.0 (68k, MIT syntax) compiled by GNU C version 1.35.
a032.C:8: duplicate enum value `red'
a032.C:8: duplicate enum value `orange'
a032.C:8: duplicate enum value `yellow'

rfg@MCC.COM (Ron Guilmette) (05/11/89)

The following program causes g++ 1.35.0- to issue invalid
error messages (shown below).  This bug apparently affects
both clases and structs.

-----------------------------------------------------------------
// Check that enum types can be declared within classes.
//
// Bug found by Wayne Allen 4/10/89 in g++ 1.34.1.1

class s {
public:
	int member;
	enum color { red, orange, yellow };
	color c;
};

int main ()
{
	return 0;
}
-----------------------------------------------------------------
g++-new-new -g -Wall -Wwrite-strings -v -S a033.C
g++ version 1.35.0-.0
 /usr/local/src/lib/sun3/g++-1.35.0-.0/gcc-cpp -+ -v -undef -D__GNU__ -D__GNUG__ -Dmc68000 -Dsun -Dunix -D__mc68000__ -D__sun__ -D__unix__ -Wall -D__HAVE_68881__ -Dmc68020 a033.C /tmp/cca18122.cpp
GNU CPP version 1.35.0-.0
 /usr/local/src/lib/sun3/g++-1.35.0-.0/gcc-cc1plus /tmp/cca18122.cpp -quiet -dumpbase a033.C -Wall -Wwrite-strings -noreg -version -G -o a033.s
GNU C++ version 1.35.0-.0 (68k, MIT syntax) compiled by GNU C version 1.35.
a033.C:9: duplicate enum value `red'
a033.C:9: duplicate enum value `orange'
a033.C:9: duplicate enum value `yellow'

rfg@MCC.COM (Ron Guilmette) (06/09/89)

Using G++ 1.35.0/Sun3, the following code gets the errors shown
below the code.  If the definition of "function" is moved to a
point *below* the declaration of the class "base", the errors
go away.

-----------------------------------------------------------------
// Check that a global level function which has already been
// either declared or defines may subsequently be declared
// to also be a friend of some class.
//
// This generates an error in G++ 1.35.0


int function (int i, int j)
{
	return i + j;
}

struct base {
	int member;

	friend int function (int, int);
};

int main ()
{
	return 0;
}
-------------------------------------------------------------------
g++-1.35.0.0 -g -Wall -Wwrite-strings -v -S a036.C
g++ version 1.35.0
 /usr/local/src/lib/sun3/g++-1.35.0.0/gcc-cpp -+ -v -undef -D__GNU__ -D__GNUG__ -D__cplusplus -Dmc68000 -Dsun -Dunix -D__mc68000__ -D__sun__ -D__unix__ -Wall -D__HAVE_68881__ -Dmc68020 a036.C /tmp/cca11336.cpp
GNU CPP version 1.35
 /usr/local/src/lib/sun3/g++-1.35.0.0/gcc-cc1plus /tmp/cca11336.cpp -quiet -dumpbase a036.C -Wall -Wwrite-strings -noreg -version -G -o a036.s
GNU C++ version 1.35.0 (68k, MIT syntax) compiled by GNU C version 1.35.
a036.C:16: friend `function' implicitly overloaded
a036.C:9: after declaration of non-overloaded `int function (int, int)'
a036.C:16: warning: `int function (int, int)' declared but never defined

rfg@MCC.COM (Ron Guilmette) (06/09/89)

The following code causes G++ 1.35.0 to abort.

-----------------------------------------------------------------
// Check that it is illegal to declare a member function which
// returns a type which has not yet been declared (even
// incompletely).
//
// This code causes G++ 1.35.0 to abort.

struct base {
	int data_member;

	struct bogus_type member (int i) {	// ERROR
		return 0;
	}
};
---------------------------------------------------------------
g++-1.35.0.0 -g -Wall -Wwrite-strings -v -S b075.C
g++ version 1.35.0
 /usr/local/src/lib/sun3/g++-1.35.0.0/gcc-cpp -+ -v -undef -D__GNU__ -D__GNUG__ -D__cplusplus -Dmc68000 -Dsun -Dunix -D__mc68000__ -D__sun__ -D__unix__ -Wall -D__HAVE_68881__ -Dmc68020 b075.C /tmp/cca12250.cpp
GNU CPP version 1.35
 /usr/local/src/lib/sun3/g++-1.35.0.0/gcc-cc1plus /tmp/cca12250.cpp -quiet -dumpbase b075.C -Wall -Wwrite-strings -noreg -version -G -o b075.s
GNU C++ version 1.35.0 (68k, MIT syntax) compiled by GNU C version 1.35.
In method struct bogus_type base::member (int):
b075.C:10: return-type `bogus_type' is an incomplete type
b075.C:10: conflicting types for `struct bogus_type base::member (int)'
In method struct bogus_type base::member (int):
b075.C:11: invalid use of undefined type `struct bogus_type'
g++-1.35.0.0: Program cc1plus got fatal signal 6.

rfg@MCC.COM (Ron Guilmette) (06/10/89)

The following code causes G++ 1.35.0/Sun3 to segfault.

--------------------------------------------------------------
// Check that if a function is *not* declared to be static
// in a given base class that it may not be declared to be
// static in any class derived from the given base class.
//
// This causes G++ 1.35.0 to segfault.

struct base
{
    virtual void member();
};

struct derived : public base
{
    static void member();		// ERROR
};

class derived *derived_ptr;

void test ()
{
    derived_ptr->member();		// Possible error
}

rfg@MCC.COM (Ron Guilmette) (07/03/89)

Using g++ 1.35.0/sun3, the compiler generates the proper error,
but it associate it with the wrong line.  Specifically, the
error is issued for the line where "s" is declared rather than
the line where the invalid assignment to "s.data_member_2" is
located.

b087.C:
----------------------------------------------------------------
// Check that it is illegal to assign to an element of an
// aggregate type object if the whole object (or the element
// being assigned to) is "const".  Note that initializations
// are an exception.

struct S {
	int data_member_1;
	int data_member_2;
};

void test ()
{
	const struct S s = { 3, 5 };

	s.data_member_2 = 99;		// ERROR
}
----------------------------------------------------------------

rfg@MCC.COM (Ron Guilmette) (07/03/89)

The following test, when compiled with G++ 1.35.0.0/sun3 generates
no errors.  I believe that an error should be generated on the
line indicated.  This would be in keeping with general philosophy
that says that private data members may only be accessed (i.e. read/written)
by member functions.

---------------------------------------------------------------------
// Check that initialization of private data members is illegal
// except via the use of an explicit constructor.

class friendly;

class base {
	int data_member_1;			// private data member
public:
	int data_member_2;
	friend class friendly;			// prevent warnings
	void function_member ();
};

void test ()
{
	base object = { 3, 5 };			// ERROR

	object.function_member ();		// prevent warnings
}
---------------------------------------------------------------------

// Ron Guilmette  -  MCC  -  Experimental Systems Kit Project
// 3500 West Balcones Center Drive,  Austin, TX  78759  -  (512)338-3740
// ARPA: rfg@mcc.com
// UUCP: {rutgers,uunet,gatech,ames,pyramid}!cs.utexas.edu!pp!rfg

tiemann@YAHI.STANFORD.EDU (Michael Tiemann) (07/29/89)

   Date: Thu, 8 Jun 89 17:12:15 CDT
   From: rfg@mcc.com (Ron Guilmette)
   Posted-Date: Thu, 8 Jun 89 17:12:15 CDT


   Using G++ 1.35.0/Sun3, the following code gets the errors shown
   below the code.  If the definition of "function" is moved to a
   point *below* the declaration of the class "base", the errors
   go away.

   -----------------------------------------------------------------
   // Check that a global level function which has already been
   // either declared or defines may subsequently be declared
   // to also be a friend of some class.
   //
   // This generates an error in G++ 1.35.0


   int function (int i, int j)
   {
	   return i + j;
   }

   struct base {
	   int member;

	   friend int function (int, int);
   };

   int main ()
   {
	   return 0;
   }
   -------------------------------------------------------------------
   g++-1.35.0.0 -g -Wall -Wwrite-strings -v -S a036.C
   g++ version 1.35.0
    /usr/local/src/lib/sun3/g++-1.35.0.0/gcc-cpp -+ -v -undef -D__GNU__ -D__GNUG__ -D__cplusplus -Dmc68000 -Dsun -Dunix -D__mc68000__ -D__sun__ -D__unix__ -Wall -D__HAVE_68881__ -Dmc68020 a036.C /tmp/cca11336.cpp
   GNU CPP version 1.35
    /usr/local/src/lib/sun3/g++-1.35.0.0/gcc-cc1plus /tmp/cca11336.cpp -quiet -dumpbase a036.C -Wall -Wwrite-strings -noreg -version -G -o a036.s
   GNU C++ version 1.35.0 (68k, MIT syntax) compiled by GNU C version 1.35.
   a036.C:16: friend `function' implicitly overloaded
   a036.C:9: after declaration of non-overloaded `int function (int, int)'
   a036.C:16: warning: `int function (int, int)' declared but never defined

There is a switch `NO_AUTO_OVERLOAD' which is presently #defined in
cplus-tree.h.  If you want C++ 2.0's automatic overloading of all
functions defined in C++ scope, comment out this #define.  It will
probably be commented out when 1.36.0 makes the scene.

Michael