cheeks@CENTRAL.SUN.COM (Mark Costlow) (07/25/89)
[sorry if you've seen this before. I mistakenly posted it instead of sending it to the mailing list] Following is a description of what we believe to be a bug in g++ 1.35.0. This is on a Sun4 under SunOS 4.0.3. The bug in g++ apparently works like this. In a method that has a typedef'ed enum as an argument, that parameter is encoded in the method's function name as _$E_n, where "n" indicates that this is the nth enum that has been typedef'ed. When a library is complied that defines numerous enum types in different modules, they each generate _E_0 when they are used as arguments because the compiler doesn't see all the enums at once. But when an application refers to more than one of these modules, the enums begin generating different function names. The workaround I came up with was to change typedef enum { X, Y, Z ... } NewType; to typedef int NewType; enum { X, Y, Z ... } ; The real fix would be to include the type name in the function name instead of the index - eg. "_E_NewType" instead of "_E_0". Run the rest of this message through sh to extract the test case t hat I worked up along with a sample run. (It compiles under cfront but not g++). Mark Costlow ....texsun!xochitl!cheeks #---------------------------------- cut here ---------------------------------- # This is a shell archive. Remove anything before this line, # then unpack it by saving it in a file and typing "sh file". # # Wrapped by <cheeks@argon> on Fri Jul 21 17:08:43 1989 # # This archive contains: # testdir # # Existing files will not be overwritten. # Error checking via wc(1) will be performed. LANG=""; export LANG echo mkdir - testdir mkdir testdir if test -f testdir/test_class_one.c then echo Ok to overwrite existing file testdir/test_class_one.c\? read answer case "$answer" in [yY]*) echo Proceeding;; *) echo Aborting; exit 1;; esac rm -f testdir/test_class_one.c if test -f testdir/test_class_one.c then echo Error: could not remove testdir/test_class_one.c, aborting exit 1 fi fi echo x - testdir/test_class_one.c cat >testdir/test_class_one.c <<'@EOF' #include <stdio.h> #include "test_class_one.h" test_class_one::test_class_one() { printf("I don't do anything\n"); }; test_class_one::~test_class_one() { printf("Neither do I\n"); }; void test_class_one::test_func_one(NewTypeOne i) { printf("Got %d\n", i); }; @EOF set `wc -lwc <testdir/test_class_one.c` if test $1$2$3 != 625261 then echo ERROR: wc results of testdir/test_class_one.c are $* should be 6 25 261 fi chmod 644 testdir/test_class_one.c if test -f testdir/test_class_one.h then echo Ok to overwrite existing file testdir/test_class_one.h\? read answer case "$answer" in [yY]*) echo Proceeding;; *) echo Aborting; exit 1;; esac rm -f testdir/test_class_one.h if test -f testdir/test_class_one.h then echo Error: could not remove testdir/test_class_one.h, aborting exit 1 fi fi echo x - testdir/test_class_one.h cat >testdir/test_class_one.h <<'@EOF' typedef enum {A, B, C} NewTypeOne; class test_class_one { public: test_class_one(); ~test_class_one(); void test_func_one(NewTypeOne); }; @EOF set `wc -lwc <testdir/test_class_one.h` if test $1$2$3 != 815151 then echo ERROR: wc results of testdir/test_class_one.h are $* should be 8 15 151 fi chmod 644 testdir/test_class_one.h if test -f testdir/test_class_two.c then echo Ok to overwrite existing file testdir/test_class_two.c\? read answer case "$answer" in [yY]*) echo Proceeding;; *) echo Aborting; exit 1;; esac rm -f testdir/test_class_two.c if test -f testdir/test_class_two.c then echo Error: could not remove testdir/test_class_two.c, aborting exit 1 fi fi echo x - testdir/test_class_two.c cat >testdir/test_class_two.c <<'@EOF' #include <stdio.h> #include "test_class_two.h" test_class_two::test_class_two() { printf("I don't do anything\n"); }; test_class_two::~test_class_two() { printf("Neither do I\n"); }; void test_class_two::test_func_two(NewTypeTwo i) { printf("Got %d\n", i); }; @EOF set `wc -lwc <testdir/test_class_two.c` if test $1$2$3 != 625261 then echo ERROR: wc results of testdir/test_class_two.c are $* should be 6 25 261 fi chmod 644 testdir/test_class_two.c if test -f testdir/test_class_two.h then echo Ok to overwrite existing file testdir/test_class_two.h\? read answer case "$answer" in [yY]*) echo Proceeding;; *) echo Aborting; exit 1;; esac rm -f testdir/test_class_two.h if test -f testdir/test_class_two.h then echo Error: could not remove testdir/test_class_two.h, aborting exit 1 fi fi echo x - testdir/test_class_two.h cat >testdir/test_class_two.h <<'@EOF' typedef enum {X, Y, Z} NewTypeTwo; class test_class_two { public: test_class_two(); ~test_class_two(); void test_func_two(NewTypeTwo); }; @EOF set `wc -lwc <testdir/test_class_two.h` if test $1$2$3 != 1015153 then echo ERROR: wc results of testdir/test_class_two.h are $* should be 10 15 153 fi chmod 644 testdir/test_class_two.h if test -f testdir/test_code.c then echo Ok to overwrite existing file testdir/test_code.c\? read answer case "$answer" in [yY]*) echo Proceeding;; *) echo Aborting; exit 1;; esac rm -f testdir/test_code.c if test -f testdir/test_code.c then echo Error: could not remove testdir/test_code.c, aborting exit 1 fi fi echo x - testdir/test_code.c cat >testdir/test_code.c <<'@EOF' #include <stream.h> #include "test_class_one.h" #include "test_class_two.h" main() { test_class_one *tc1 = new test_class_one; test_class_two *tc2 = new test_class_two; cout << "Hello world ...\n"; tc1->test_func_one(A); tc2->test_func_two(X); cout << "Hello again ...\n"; tc1->test_func_one(B); tc2->test_func_two(Y); cout << "Hello for the last time ...\n"; tc1->test_func_one(C); tc2->test_func_two(Z); } @EOF set `wc -lwc <testdir/test_code.c` if test $1$2$3 != 2143456 then echo ERROR: wc results of testdir/test_code.c are $* should be 21 43 456 fi chmod 644 testdir/test_code.c if test -f testdir/test_code.h then echo Ok to overwrite existing file testdir/test_code.h\? read answer case "$answer" in [yY]*) echo Proceeding;; *) echo Aborting; exit 1;; esac rm -f testdir/test_code.h if test -f testdir/test_code.h then echo Error: could not remove testdir/test_code.h, aborting exit 1 fi fi echo x - testdir/test_code.h cat >testdir/test_code.h <<'@EOF' typedef enum {A, B, C} NewTypeOne; typedef enum {X, Y, Z} NewTypeTwo; @EOF set `wc -lwc <testdir/test_code.h` if test $1$2$3 != 21270 then echo ERROR: wc results of testdir/test_code.h are $* should be 2 12 70 fi chmod 644 testdir/test_code.h if test -f testdir/Makefile then echo Ok to overwrite existing file testdir/Makefile\? read answer case "$answer" in [yY]*) echo Proceeding;; *) echo Aborting; exit 1;; esac rm -f testdir/Makefile if test -f testdir/Makefile then echo Error: could not remove testdir/Makefile, aborting exit 1 fi fi echo x - testdir/Makefile cat >testdir/Makefile <<'@EOF' CC = g++ -v OBJS = test_code.o test_class_one.o test_class_two.o all: clean test_code test_code: $(OBJS) $(CC) -o test_code $(OBJS) test_code.o: test_code.c $(CC) -c test_code.c test_class_one.o: test_class_one.c $(CC) -c test_class_one.c test_class_two.o: test_class_two.c $(CC) -c test_class_two.c clean: rm -f *.o test_code @EOF set `wc -lwc <testdir/Makefile` if test $1$2$3 != 2038342 then echo ERROR: wc results of testdir/Makefile are $* should be 20 38 342 fi chmod 644 testdir/Makefile if test -f testdir/Sample_Run then echo Ok to overwrite existing file testdir/Sample_Run\? read answer case "$answer" in [yY]*) echo Proceeding;; *) echo Aborting; exit 1;; esac rm -f testdir/Sample_Run if test -f testdir/Sample_Run then echo Error: could not remove testdir/Sample_Run, aborting exit 1 fi fi echo x - testdir/Sample_Run cat >testdir/Sample_Run <<'@EOF' Script started on Fri Jul 21 16:37:36 1989 <sodium> [1] ->make CC="CC -v" rm -f *.o test_code CC -v -c test_code.c CC test_code.c: cc -c -v test_code..c /lib/cpp -undef -Dunix -Dsun -Dsparc test_code..c >/tmp/cpp.07149.0.i /lib/ccom - </tmp/cpp.07149.0.i >/tmp/ccom.07149.1.s rm /tmp/cpp.07149.0.i /bin/as -o test_code..o -Q /tmp/ccom.07149.1.s rm /tmp/ccom.07149.1.s CC -v -c test_class_one.c CC test_class_one.c: cc -c -v test_class_one..c /lib/cpp -undef -Dunix -Dsun -Dsparc test_class_one..c >/tmp/cpp.07161.0.i /lib/ccom - </tmp/cpp.07161.0.i >/tmp/ccom.07161.1.s rm /tmp/cpp.07161.0.i /bin/as -o test_class_one..o -Q /tmp/ccom.07161.1.s rm /tmp/ccom.07161.1.s CC -v -c test_class_two.c CC test_class_two.c: cc -c -v test_class_two..c /lib/cpp -undef -Dunix -Dsun -Dsparc test_class_two..c >/tmp/cpp.07173.0.i /lib/ccom - </tmp/cpp.07173.0.i >/tmp/ccom.07173.1.s rm /tmp/cpp.07173.0.i /bin/as -o test_class_two..o -Q /tmp/ccom.07173.1.s rm /tmp/ccom.07173.1.s CC -v -o test_code test_code.o test_class_one.o test_class_two.o cc -o test_code -v test_code.o test_class_one.o test_class_two.o -lC /bin/ld -dc -dp -e start -X -o test_code /usr/lib/crt0.o test_code.o test_class_one.o test_class_two.o -lC -lc /bin/ld -dc -dp -e start -X -o test_code /usr/lib/crt0.o __ctdt.o test_code.o test_class_one.o test_class_two.o -lC -lc <sodium> [2] ->./test_code I don't do anything I don't do anything Hello world ... Got 0 Got 0 Hello again ... Got 1 Got 1 Hello for the last time ... Got 2 Got 2 <sodium> [3] ->make CC="g++ -v" rm -f *.o test_code g++ -v -c test_code.c g++ version 1.35.0 /usr/local/lib/gcc-cpp -+ -v -undef -D__GNU__ -D__GNUG__ -D__cplusplus -Dsparc -Dsun -Dunix -D__sparc__ -D__sun__ -D__unix__ test_code.c /tmp/cca07208.cpp GNU CPP version 1.35 /usr/local/lib/gcc-cc1plus /tmp/cca07208.cpp -quiet -dumpbase test_code.c -noreg -version -o /tmp/cca07208.s GNU C++ version 1.35.0 (sparc) compiled by GNU C version 1.35. as /tmp/cca07208.s -o test_code.o g++ -v -c test_class_one.c g++ version 1.35.0 /usr/local/lib/gcc-cpp -+ -v -undef -D__GNU__ -D__GNUG__ -D__cplusplus -Dsparc -Dsun -Dunix -D__sparc__ -D__sun__ -D__unix__ test_class_one.c /tmp/cca07212.cpp GNU CPP version 1.35 /usr/local/lib/gcc-cc1plus /tmp/cca07212.cpp -quiet -dumpbase test_class_one.c -noreg -version -o /tmp/cca07212.s GNU C++ version 1.35.0 (sparc) compiled by GNU C version 1.35. as /tmp/cca07212.s -o test_class_one.o g++ -v -c test_class_two.c g++ version 1.35.0 /usr/local/lib/gcc-cpp -+ -v -undef -D__GNU__ -D__GNUG__ -D__cplusplus -Dsparc -Dsun -Dunix -D__sparc__ -D__sun__ -D__unix__ test_class_two.c /tmp/cca07216.cpp GNU CPP version 1.35 /usr/local/lib/gcc-cc1plus /tmp/cca07216.cpp -quiet -dumpbase test_class_two.c -noreg -version -o /tmp/cca07216.s GNU C++ version 1.35.0 (sparc) compiled by GNU C version 1.35. as /tmp/cca07216.s -o test_class_two.o g++ -v -o test_code test_code.o test_class_one.o test_class_two.o g++ version 1.35.0 /usr/local/lib/gcc-ld++ -o test_code -C /usr/local/lib/crt0+.o test_code.o test_class_one.o test_class_two.o -lg++ /usr/local/lib/gcc-gnulib -lc test_code.o: Undefined symbol _test_func_two_PStest_class_two_E$_1 referenced from text test_code.o: Undefined symbol _test_func_two_PStest_class_two_E$_1 referenced from text test_code.o: Undefined symbol _test_func_two_PStest_class_two_E$_1 referenced from text *** Error code 1 make: Fatal error: Command failed for target `test_code' <sodium> [4] ->^D script done on Fri Jul 21 16:38:22 1989 @EOF set `wc -lwc <testdir/Sample_Run` if test $1$2$3 != 774103504 then echo ERROR: wc results of testdir/Sample_Run are $* should be 77 410 3504 fi chmod 644 testdir/Sample_Run chmod 755 testdir exit 0 Mark Costlow ....texsun!xochitl!cheeks
grunwald@flute.cs.uiuc.edu (Dirk Grunwald) (07/30/89)
I also ran into this bug in 1.35.1+ and forgot to report it. Another workaround is to change your function to use `int' and not the enum. -- Dirk Grunwald -- Univ. of Illinois (grunwald@flute.cs.uiuc.edu)