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!cheeksgrunwald@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)