Quuxplusone / LLVMBugzillaTest

0 stars 0 forks source link

CBE output doesn't compile with GCC 4.2.X #1625

Closed Quuxplusone closed 16 years ago

Quuxplusone commented 16 years ago
Bugzilla Link PR1583
Status RESOLVED FIXED
Importance P normal
Reported by Reid Spencer (rspencer@reidspencer.com)
Reported on 2007-07-30 11:06:06 -0700
Last modified on 2007-08-03 18:53:47 -0700
Version 1.0
Hardware PC Linux
CC llvm-bugs@lists.llvm.org
Fixed by commit(s)
Attachments
Blocks
Blocked by
See also
In testing PR1146, I noticed that a lot of CBE tests in the test-suite are
failing. I've updated my compilation environmen tto use GCC 4.2.1. The output is
fine when compiled with gcc but the test-suite uses g++ to compile them and it
fails with, for example:

g++ Output/ackermann.cbe.c -o Output/ackermann.cbe
Output/ackermann.cbe.c:267: error: ‘::main’ must return ‘int’
Output/ackermann.cbe.c:288: error: redefinition of
‘l_struct_2E_std_3A__3A_ctype_base _ZSt8__ioinit’
Output/ackermann.cbe.c:281: error: ‘l_struct_2E_std_3A__3A_ctype_base
_ZSt8__ioinit’ previously declared here
Output/ackermann.cbe.c:289: error: redefinition of ‘unsigned char _2E_str [7]’
Output/ackermann.cbe.c:282: error: ‘unsigned char _2E_str [7]’ previously
declared here
Output/ackermann.cbe.c:290: error: redefinition of ‘unsigned char _2E_str1 [4]’
Output/ackermann.cbe.c:283: error: ‘unsigned char _2E_str1 [4]’ previously
declared here
Output/ackermann.cbe.c:378: error: ‘::main’ must return ‘int’

I'm not sure why the makefiles compile with g++ instead of gcc. It probably
shouldn't.
Quuxplusone commented 16 years ago
Interestingly enough, if you change the makefiles to link with gcc instead of
g++ then you get:

gcc -L/proj/llvm/PR1146/installed/lib/gcc/i686-pc-linux-gnu/4.0.1 -
L/proj/llvm/PR1146/installed/lib Output/ackermann.cbe.c \
    -fno-strict-aliasing -O2 -fno-inline  -o Output/ackermann.cbe
Output/ackermann.cbe.c:275: warning: conflicting types for built-in function
‘malloc’
Output/ackermann.cbe.c: In function ‘main’:
Output/ackermann.cbe.c:378: warning: return type of ‘main’ is not ‘int’
/tmp/ccqUd2lQ.o: In function `main':
ackermann.cbe.c:(.text+0xd5): undefined reference to `std::cout'
ackermann.cbe.c:(.text+0xda): undefined reference to `std::basic_ostream<char,
std::char_traits<char> >& std::operator<< <std::char_traits<char>
>(std::basic_ostream<char, std::char_traits<char> >&, char const*)'
ackermann.cbe.c:(.text+0xe6): undefined reference to `std::basic_ostream<char,
std::char_traits<char> >::operator<<(int)'
ackermann.cbe.c:(.text+0xf6): undefined reference to `std::basic_ostream<char,
std::char_traits<char> >& std::operator<< <std::char_traits<char>
>(std::basic_ostream<char, std::char_traits<char> >&, char const*)'
ackermann.cbe.c:(.text+0x102): undefined reference to `std::basic_ostream<char,
std::char_traits<char> >::operator<<(int)'
ackermann.cbe.c:(.text+0x10a): undefined reference to `std::basic_ostream<char,
std::char_traits<char> >& std::endl<char, std::char_traits<char>
>(std::basic_ostream<char, std::char_traits<char> >&)'
ackermann.cbe.c:(.text+0x112): undefined reference to `std::basic_ostream<char,
std::char_traits<char> >::operator<<(std::basic_ostream<char,
std::char_traits<char> >& (*)(std::basic_ostream<char, std::char_traits<char>
>&))'
/tmp/ccqUd2lQ.o: In function `global destructors keyed to _Z3Ackii':
ackermann.cbe.c:(.text+0x19e): undefined reference to
`std::ios_base::Init::~Init()'
/tmp/ccqUd2lQ.o: In function `global constructors keyed to _Z3Ackii':
ackermann.cbe.c:(.text+0x1be): undefined reference to
`std::ios_base::Init::Init()'
collect2: ld returned 1 exit status

which is very weird for a C program.
Quuxplusone commented 16 years ago

Actually, its not that weird. The original source in this case is a C++ program which uses the stdc++ library. Simply adding -lstdc++ to the link line allows it to link properly.

Quuxplusone commented 16 years ago
The issue is entirely with the CBE output. I believe it is correct for GCC 4.2
to be making the redefinition of statics illegal. The CBE has depended on lax
reporting of static redefinitions in the past, but it should not do this. I
believe this was done to solve the initializer reference problem.

The CBE generates things like:

static char *foo;
static char *foo = "";

The first foo being a declaration and the second being a definition. However,
GCC 4.2 is taking them both as definitions and issuing a redefinition error.
Quuxplusone commented 16 years ago
Resolved with r40797. The makefiles just needed to compile .cbe.c and .s files
appropriately with the right libraries for the llvm-gcc compiler in use.