[gnu.g++.bug] SERIOUS BUG: No code generated

jj@idris.id.dk (Jesper Joergensen [ris]) (01/20/90)

THIS BUG IS A SERIOUS ONE, since the compiler fails to emit an error message
for an invalid statement, BUT NO CODE IS GENERATED for the statement.

It is connected to the good old const problem, towards which the compiler's
attitude has changed a lot across the latest releases. Some other error
messages are still missing, which I will try and summarize in this postng as
well.

I am using:	g++ 1.36.3	(just installed it)
based on:	gcc 1.36	(can't get my hands on 1.36.92 anywhere)
under:		Ultrix V2.2-1 Worksystem V1.1 System #2
on a:		DEC VAXstation 2000

Much of the errors missing were present in 1.36.3-, while some of them have
never been. I am very confused, since nothing has changed in the language since
1.36.3-. I AM VERY CONFUSED and humbly asks for an explanation, PLEASE respond.

The below program contains a series of errors, which does not cause any
messages from the compiler. All these errors are marked with an // ERROR: ...
comment. Some of the methods have sideeffects to show there invocations.

****** SAMPLE PROGRAM START ******
extern "C" int printf(const char* ...) ;

class Test {
  const char *name ;
  int member ;
public:
  Test(const char* name1, int member1) { name = name1 ; member = member1 ; }
  Test(const Test &x) { member = x.member ; }

  /* This method is non-const, but it returns a const result */
  const Test &operator=(const Test &r) {
    member = - r.member ;		// NOTE: side effect
    return *this ;
  }

  /* This method is const and it returns a pointer to a const result */
  const Test *operator&() const {	// NOTE: side effect of operator =
    *this = *this ;	// ERROR: non-const method called within const method
    return this ;
  }

  /* This friend modifies the non-const reference argument */
  friend void change_sign(Test &x) {
    x.member = - x.member ;
  }

  /* This friend prints the name and contents of the class object */
  friend void print(const Test &x) {
    printf("%s.member = %d\n", x.name, x.member) ;
  }
} ;

int main(int argc, const char *argv[]) {
  const Test C("C",1) ;
  Test V("V",2) ;

  &V ;			// should change sign of V.member

  print(C) ; print(V) ;

  C = V ;		// ERROR: non-const method applied to const object

  print(C) ; print(V) ;

  (V = C) = V ;		// ERROR: non-const method applied to const object
			//        (result of  (V = C)  is reference to const)

  print(C) ; print(V) ;

  change_sign(V = C) ;	// ERROR: passing non-const reference from const object
			//        (result of  (V = C)  is reference to const)

  print(C) ; print(V) ;

  *(&V) = C ;		// ERROR: non-const method applied to const object
			//        (the result of  &V  is a pointer to const)

  print(C) ; print(V) ;

  return 0 ;
}
******* SAMPLE PROGRAM END *******

NON of the above errors were detected by the compiler and some of the erroneuos
statements doesn't have effect when executed. Below is the output from the
program.

****** PROGRAM OUTPUT START ******
C.member = 1
V.member = 2	/* 1/ no effect of &V (should change sign) */
C.member = 1	/* 2/ C = V had no effect */
V.member = 2
C.member = 1	/* 3/ (V = C) = V changed sign of C twice in V */
V.member = 1	/*    hence it corresponds to  V = C ; V = V ; */
C.member = 1
V.member = 1	/* 4/ change_sign changed sign of the result in V */
C.member = 1
V.member = 1	/* 5/ no effect of *(&V) = C (should be negated C.member) */
******* PROGRAM OUTPUT END *******

1/ the & operator calls the = operator on *this, so the sign should be changed
   implicitly on the argument to &. This does not happen, since = is not
   invoked at all (it IS an illegal invocation, but no error shows up).
2/ the assignment C = V had no effect on C, since = is not invoked (it IS an
   illegal invocation, but still no error shows up).
3/ shows the expected result since the result of = is a reference to the left
   hand operand, but it should still be illegal to invoke a non-const method
   on a const function result.
4/ shows the expected result since the result of = is a reference to the left
   hand operand, but is should still be illegal to pass the const reference
   result as a non-const reference parameter.
5/ the = operator was not invoked, since that would have stored the negative
   value of C.member in V.member. It is also an illegal invocation of the
   non-const method = on the const object *(&V), but still no error message
   shows up.

Can you explain this to me ?????


	Thanks in advanve

	Jesper Jorgensen	jj@idris.id.dk

	Research associate
	Department of Computer Science
	Technical University of Denmark
	DK-2800 Lyngby
	DENMARK