[gnu.g++.bug] Problem with enums, refs: g++ 1.36.2

keith@csli.Stanford.EDU (Keith Nishihara) (12/29/89)

There is a possible bug in g++ observed in 1.36.2 on a Pmax (DS 3100),
and also 1.35.0 (sun 4): an expected warning/error is not output,
and wrong code is generated. I am not sure whether it is associated with
enums, or passing references to functions, or maybe something esoteric
like casts on lvalues.

In the code below, function test sets the value of its (int &) parameter.

On line 10, I tried simply passing the enum:  However, I believe that
automatic promotion of enums to ints is no longer performed under 2.0
rules, so on line 11, I tried explicitly casting the enum into an int.

----------------------------------------
#include <stdio.h>

void test(int &i) { i = 2; }

enum k { A, B, C, D, E, F };

main()
{
    enum k i = D, j = E;
    test(i);					// line 10
    test((int)j);				// line 11
    printf("i = %d, j = %d\n", i, j);
}
----------------------------------------

The expected result was a warning on line 10 (enum promoted to type int)
and the output
	i = 2, j = 2

Both versions of g++ compiled with no warnings, giving me the output:
	i = 2, j = 4

----------------------------------------

By the way, cfront 1.2 gives me the expected error:
"k.c", line 10: error: bad initializer type: enum k ( int & expected)
but still screws up on line 11, generating the code
    int _au0__I1;
    test ( (int *)( (_au0__I1 = (((int )_au1_j ))), (& _au0__I1 )) )
which gives the output:
	i = 3, j = 4

I note that using test((int &)j); gives the expected results;
I guess that the more explicit cast is OK.
I also note that the following code is doing conceptually a similar
thing (wrt casting) as line 11, but without the unexpected effect:

    void test2(float f) { printf("test2: %f\n", (double)f); }

    { enum k i = D; int p = 10;
      test2(i); test2((int)i); test2((float)i); test2((double)i);
      test2(p); test2((pnt)p); test2((float)p); test2((double)p);
    }

giving me the expected answers 3.0, 3.0, 3.0, 3.0, 10.0, 10.0, 10.0, 10.0.
Here, at least, the function prototype appears effectively to cast
the argument _again_ after my explicit cast.
Over to the language lawyers to sort out what really should happen!

Neil/.		Neil%teleos.com@ai.sri.com