Bug or feature: symbol names of global/extern variables
Hello, I don't know whether it is a bug or feature and I searched through the mailing lists without success therefor I write my question this way: If you have a global variable inside a cpp file and create a library out of that, the symbol name for that global variable does in no way take the variable type into account. A user of that variable can "make" it any type with its extern declaration and thus produce subtle errors. An example: lib.cpp: int maximum; int minimum; static bool init ( ) { maximum = 2; minimum = -7; } static bool initialized = init ( ); --- Create a library out of that lib.cpp file. Then compile the following main.cpp and link it against the library: main.cpp: --- extern double maximum; extern intminimum; void main (int, char**) { // Assume you are on a machine where the sizeof (int) is 4 bytes // and the sizeof (double) is 8 bytes. assert (minimum == -7); { maximum = 2342343242343.3; } assert (minimum == -7); return 0; } --- The main.o will perfectly link with the library although main.o needs a double variable named maximum and the lib only offers an int variable named maximum. Because the symbol name does in no way reflect the variable type, everything links fine but in fact the variable minimum gets scrambled in this example because maximum is accessed as if it is a double variable thus overwriting 4 additional bytes (in the case the 4 bytes of the variable minimum). The assertion will show that. I tested that on Windows with Visual C++ as well and there main.obj won't link because the variable type is part of the symbol name and everthing is fine. I think it would be very very important for the binary interface (ELF here, or?) to have that feature as well. What do you think? Regards, Wolfgang Roemer
Re: Bug or feature: symbol names of global/extern variables
Wolfgang Roemer wrote on 06/10/2005 10:52:35: > > I don't know whether it is a bug or feature and I searched through the mailing > lists without success therefor I write my question this way: > > If you have a global variable inside a cpp file and create a library out of > that, the symbol name for that global variable does in no way take the > variable type into account. A user of that variable can "make" it any type > with its extern declaration and thus produce subtle errors. An example: It's a feature. It is undefined behavior to have conflicting declarations in different translation units. [...] > > I tested that on Windows with Visual C++ as well and there main.obj won't link > because the variable type is part of the symbol name and everthing is fine. In that case, how does VC++ implement cout,cin, construction? In libstdc++ (well, at least in gcc-3.4) it is implemented by doing something like: namespace std{ ... // Note that this is different from 's definition of cin // (it's declared as "extern istream cin" in there). char cin[ sizeof(istream) ]; ... ios::Init::Init() { if (count++ == 0) new (&cin) istream(cin_constuction_flags); } > I think it would be very very important for the binary interface (ELF here, > or?) to have that feature as well. What do you think? Doing so may break the (standardized) ABI. Michael
Re: Bug or feature: symbol names of global/extern variables
Hello Michael, first of all: Thanks for the fast reply! On Thu Oct 06, 2005 10:33, you wrote: >> [..] >> >> It's a feature. It is undefined behavior to have conflicting declarations >> in different translation units. >> [...] Well, but shouldn't there at least be a warning during linking!? >> [..] >> In that case, how does VC++ implement cout,cin, construction? >> In libstdc++ (well, at least in gcc-3.4) it is implemented by doing >> something like: >> >> namespace std{ >> ... >> >> // Note that this is different from 's definition of cin >> // (it's declared as "extern istream cin" in there). >> char cin[ sizeof(istream) ]; >> ... >> ios::Init::Init() >> { >>if (count++ == 0) >> new (&cin) istream(cin_constuction_flags); >> >> } I don't know how VC++ implements cout, cin. I just checked the symbol names with the dumpbin.exe tool that is part of the VC++ Suite and there it is clearly marked as "maximum (int)". And during the attempt to link you get a unresolved symbol error saying that main.o needs "maximum (double)" but lib only offers "maximum (int)" and that's very helpful. I encountered this behaviour on Linux because of a very strange SEGV and I was finally able to track that down to an extern variable that was used in the wrong way and thus I found the mentioned behaviour. I did not take a look at the VC++ libc implementation etc. I just checked it from the user perspective. Thanks, WR
Re: Bug or feature: symbol names of global/extern variables
Wolfgang Roemer wrote on 06/10/2005 12:03:39: > Hello Michael, > > first of all: Thanks for the fast reply! > > On Thu Oct 06, 2005 10:33, you wrote: > >> [..] > >> > >> It's a feature. It is undefined behavior to have conflicting declarations > >> in different translation units. > >> [...] > > Well, but shouldn't there at least be a warning during linking!? I am not a gcc developer, but as a user I can see the benefits of this. > > >> [..] > >> In that case, how does VC++ implement cout,cin, construction? [] > > I don't know how VC++ implements cout, cin. I just checked the symbol names > with the dumpbin.exe tool that is part of the VC++ Suite and there it is > clearly marked as "maximum (int)". And during the attempt to link you get a > unresolved symbol error saying that main.o needs "maximum (double)" but lib > only offers "maximum (int)" and that's very helpful. I encountered this > behaviour on Linux because of a very strange SEGV and I was finally able to > track that down to an extern variable that was used in the wrong way and thus > I found the mentioned behaviour. I did not take a look at the VC++ libc > implementation etc. I just checked it from the user perspective. > It sounds as if the symbol is still "maximum" and it is annotated with its type (something like debug information). I should be possible to hack the linker to emit a warning for symbols with conflicting debug information. This is the wrong list for linker enhancements. You should look for binutils mailing lists. However "collect2" which is part of gcc and is called before the linker (for C++)- could also detect this and give the same warning. I would bet that collect2 is the wrong place for this enhancement because it will work only for C++, not for C. Michael
Re: Bug or feature: symbol names of global/extern variables
Michael Veksler wrote: It sounds as if the symbol is still "maximum" and it is annotated with its type (something like debug information). I should be possible to hack the linker to emit a warning for symbols with conflicting debug information. Nice idea! This is the wrong list for linker enhancements. You should look for binutils mailing lists. However "collect2" which is part of gcc and is called before the linker (for C++)- could also detect this and give the same warning. I would bet that collect2 is the wrong place for this enhancement because it will work only for C++, not for C. If the linker did this, then it would even work across languages, e.g. importing a C symbol from an Ada unit, and vice versa. Michael
Re: Bug or feature: symbol names of global/extern variables
Hello, so it seems as if it would be best if I post that to the binutils mailing list. Agreed? WR On Thu Oct 06, 2005 11:57, Robert Dewar wrote: >> Michael Veksler wrote: >> > It sounds as if the symbol is still "maximum" and it is annotated with >> > its type (something like debug information). I should be possible to >> > hack the linker to emit a warning for symbols with conflicting debug >> > information. >> >> Nice idea! >> >> > This is the wrong list for linker enhancements. You should look for >> > binutils mailing lists. However "collect2" which is part of gcc and is >> > called before the linker (for C++)- could also detect this and give >> > the same warning. I would bet that collect2 is the wrong place for >> > this enhancement because it will work only for C++, not for C. >> >> If the linker did this, then it would even work across languages, >> e.g. importing a C symbol from an Ada unit, and vice versa. >> >> > Michael
Re: Bug or feature: symbol names of global/extern variables
Wolfgang Roemer wrote: Hello, so it seems as if it would be best if I post that to the binutils mailing list. Agreed? Indeed. This is not a simple change, but it would make a nice well defined project for someone to work on! > It sounds as if the symbol is still "maximum" and it is annotated with > its type (something like debug information). I should be possible to > hack the linker to emit a warning for symbols with conflicting debug > information.
Bug or feature: symbol names of global/extern variables
Hello, I encountered a subtle SEGV in a program and was able to track the problem down to symbol names concerning global/extern variables. I discussed that with some guys from the GCC project (see recipient list) and we came to the conclusion it would make more sense to share our thoughts with you. Here the problem: If you have a global variable inside a cpp file and create a library out of that, the symbol name for that global variable does in no way take the type of the variable into account. A user of that variable can "make" it any type with an "extern" declaration and thus produce subtle errors. An example: lib.cpp int maximum; int minimum; static bool init ( ) { maximum = 2; minimum = -7; } static bool initialized = init ( ); --- Create a library out of that lib.cpp file. Then compile the following main.cpp and link it against the library: - main.cpp -- extern double maximum; extern int minimum; void main (int, char**) { // Assume you are on a machine where the sizeof (int) is 4 bytes // and the sizeof (double) is 8 bytes. assert (minimum == -7); { maximum = 2342343242343.3; } assert (minimum == -7); return 0; } - The main.o will perfectly link with the library although main.o needs a double variable named maximum and the lib only offers an int variable named maximum. Because the symbol name does in no way reflect the variable type, everything links fine but in fact the variable named "minimum" gets scrambled in this example because "maximum" is accessed as if it is a double variable thus overwriting 4 additional bytes (in this case the 4 bytes of the variable minimum). The assertion will show that. I tested that on Windows with Visual C++ as well and there main.obj doesn't link because the variable type is part of the symbol name and everthing is fine. I think it would be very very important for the binary interface to have that feature as well. Regards, Wolfgang Roemer
Re: Bug or feature: symbol names of global/extern variables
Wolfgang Roemer wrote: The main.o will perfectly link with the library although main.o needs a double variable named maximum and the lib only offers an int variable named maximum. Because the symbol name does in no way reflect the variable type, everything links fine but in fact the variable named "minimum" gets scrambled in this example because "maximum" is accessed as if it is a double variable thus overwriting 4 additional bytes (in this case the 4 bytes of the variable minimum). The assertion will show that. I tested that on Windows with Visual C++ as well and there main.obj doesn't link because the variable type is part of the symbol name and everthing is fine. I think it would be very very important for the binary interface to have that feature as well. I actually disagree with this, I think attempting to make the link fail here would be a mistake. What is more interesting is a proposal to have the linker give warnings if the debug descriptions of symbols do not match. That can even work across languages.
Re: Bug or feature: symbol names of global/extern variables
On Thu Oct 06, 2005 14:50, Robert Dewar wrote: >> [..] >> >> I actually disagree with this, I think attempting to make the link fail >> here would be a mistake. Why do you think that this would be a mistake? WR
Re: Question about Machine Description
Ian Lance Taylor writes: > This kind of error generally means that the operand predicate accepts > an operand which no constraint matches. If the predicate (e.g., > register_operand) accepts an operand, then there must be a constraint > that matches it. Otherwise you will get an error in > constrain_operands, such as the above. and later: > When I said this: > >> > This kind of error generally means that the operand predicate accepts >> > an operand which no constraint matches. If the predicate (e.g., >> > register_operand) accepts an operand, then there must be a constraint >> > that matches it. Otherwise you will get an error in >> > constrain_operands, such as the above. > > I mean that, in the instruction above, any operand which matches > nonimmediate_operand must be matched by at least one of the > constraints 'm' or 'r', and any operand which matches const0_operand > must match the constraint 'n'. This might confuse people. It sounds your first quote is saying that everything accepted by a predicate must also match at least one constraint, and of course that isn't true. E.g. register_operand accepts registers from any class, whereas 'r' only matches GENERAL_REGS. And it's usually OK (but not good practice, because it generates poor code) for a nonimmediate_operand to only provide 'r' constraints. More realistically, it's OK for a nonimmediate_operand to only allow memory constraints for some combinations of operands. It's reload's job to fix this sort thing. I realise I'm not telling you (Ian) anything new here, I just thought it was worth clarifying. Richard
Bug or feature: symbol names of global/extern variables
I don't think this has anything to do with binutils; whether linking succeeds exclusively depends on the mangling method used (VC does mangle data object names, while g++ doesn't). AFAIK the standard only talks about function signatures, meaning mangling data object names is neither prohibited nor required (i.e. implementation defined) [7.5 clause 9 deals with that]. Jan >>> Wolfgang Roemer <[EMAIL PROTECTED]> 06.10.05 14:44:58 >>> Hello, I encountered a subtle SEGV in a program and was able to track the problem down to symbol names concerning global/extern variables. I discussed that with some guys from the GCC project (see recipient list) and we came to the conclusion it would make more sense to share our thoughts with you. Here the problem: If you have a global variable inside a cpp file and create a library out of that, the symbol name for that global variable does in no way take the type of the variable into account. A user of that variable can "make" it any type with an "extern" declaration and thus produce subtle errors. An example: lib.cpp int maximum; int minimum; static bool init ( ) { maximum = 2; minimum = -7; } static bool initialized = init ( ); --- Create a library out of that lib.cpp file. Then compile the following main.cpp and link it against the library: - main.cpp -- extern double maximum; extern intminimum; void main (int, char**) { // Assume you are on a machine where the sizeof (int) is 4 bytes // and the sizeof (double) is 8 bytes. assert (minimum == -7); { maximum = 2342343242343.3; } assert (minimum == -7); return 0; } - The main.o will perfectly link with the library although main.o needs a double variable named maximum and the lib only offers an int variable named maximum. Because the symbol name does in no way reflect the variable type, everything links fine but in fact the variable named "minimum" gets scrambled in this example because "maximum" is accessed as if it is a double variable thus overwriting 4 additional bytes (in this case the 4 bytes of the variable minimum). The assertion will show that. I tested that on Windows with Visual C++ as well and there main.obj doesn't link because the variable type is part of the symbol name and everthing is fine. I think it would be very very important for the binary interface to have that feature as well. Regards, Wolfgang Roemer
Re: Bug or feature: symbol names of global/extern variables
Wolfgang Roemer wrote on 06/10/2005 16:14:03: > On Thu Oct 06, 2005 14:50, Robert Dewar wrote: > >> [..] > >> > >> I actually disagree with this, I think attempting to make the link fail > >> here would be a mistake. > > Why do you think that this would be a mistake? > I agree with Robert, it would be a mistake. For several reasons: 1. There is code out there that depends on this feature (e.g. initialization of std::cin and friends). You don't want to break it. 2. I think that it will break C. As I remember, it is sometimes legal in C (or in some dialects of C) to have conflicting types. You may define in one translation unit: char var[5]; and then go on and define in a different translation unit: char var[10]; The linker will merge both declarations and allocate at least 10 bytes for 'var' (ld's --warn-common will detect this). I don't have C99's spec near me so I can't tell if this is really part of C99 or of some dialect of C. If the linker only warns on mismatched types it gives users a choice. A user can choose to run the linker with --fatal-warnings (or gcc -Wl,--fatal-warnings) and get an error. --fatal-warnings seems to be gnu-ld's equivalent of gcc's -Werror (at least as I understand ld's man page). Michael
Re: Bug or feature: symbol names of global/extern variables
Hello Michael, On Thu Oct 06, 2005 15:54, Michael Veksler wrote: [..] >> 2. I think that it will break C. As I remember, it is sometimes >> legal in C (or in some dialects of C) to have conflicting types. >> You may define in one translation unit: >> char var[5]; >> and then go on and define in a different translation unit: >> char var[10]; >> The linker will merge both declarations and allocate at least >> 10 bytes for 'var' (ld's --warn-common will detect this). that is interesting: If the linker would behave that way, I wouldn't get the error because the needed 8 bytes for a double would be allocated. WR
New branch opened: dataflow-branch
This branch contains the work Ken Zadeck and I have been doing replacing the backend dataflow (such as live register analysis) with df.c based dataflow. It currently bootstraps on x86-linux-gnu, and powerpc-linux-gnu, and powerpc-darwin. Currently, reg-stack doesn't like accurate liveness info (IE with unset variables removed), so that the more accurate liveness analysis is disabled at some points in the compiler. The branch may be slower or faster than mainline right now, we haven't concetrated on timings, but we are confident it will be faster when we are done. The branch produces about 1% better spec scores, due to better liveness information being computed. I will document the branch in wwwdocs soon.
Re: Bug or feature: symbol names of global/extern variables
>>> Wolfgang Roemer <[EMAIL PROTECTED]> 06.10.05 16:02:37 >>> >On Thu Oct 06, 2005 15:54, Michael Veksler wrote: >[..] >>> 2. I think that it will break C. As I remember, it is sometimes >>> legal in C (or in some dialects of C) to have conflicting types. >>> You may define in one translation unit: >>> char var[5]; >>> and then go on and define in a different translation unit: >>> char var[10]; >>> The linker will merge both declarations and allocate at least >>> 10 bytes for 'var' (ld's --warn-common will detect this). > >that is interesting: If the linker would behave that way, I wouldn't get the >error because the needed 8 bytes for a double would be allocated. I think your example had the variables initialized; this is a difference. The linker does behave as Michael described for uninitialized (aka common) variables; gcc's -fno-common suppresses this behavior. Jan
Re: Bug or feature: symbol names of global/extern variables
Michael Veksler wrote: Why do you think that this would be a mistake? (you in the above is dewar) Michael has exactly stated my reasons :-)
Re: Problems with the m32c target and M16C6N cpu
Hi DJ, finally, I could try your proposal with the reset.S file. It works fine in the KD30 debugger, but unfortunately, the program doesn't run when I flash the srec directly. Do you have an idea on what's going wrong? Frank References: http://gcc.gnu.org/ml/gcc/2005-09/msg00067.html http://gcc.gnu.org/ml/gcc/2005-09/msg00070.html DJ Delorie wrote on Sat, 3 Sep 2005: The most likely problem is that you're not providing a reset vector that points at your program, so the board doesn't know the starting location (neither kd30 nor the flash program honor the "start address" s-record). I should probably have the tools do that automatically. With the tools you have, create a reset.S file that looks like this: .section ".resetvec","a" .word _start .text and add that to your compile line. I just checked in a fix yesterday that lets you do this: typedef void (*ifunc)() __attribute__((mode(SI))); extern void start(); const ifunc __attribute__((section(".resetvec"))) reset_vector = start; Anyway, you can also use "objdump -f" on the ELF executable to find out where it wants its start address, then flash the chip, then verify that the program was loaded there. Then you can double-click on $pc in the register window to force it to start in the right place. ___ Gesendet von Yahoo! Mail - Jetzt mit 1GB Speicher kostenlos - Hier anmelden: http://mail.yahoo.de
SEGV in do_simple_structure_copy
Hello, The Ada testcase below, compiled with -O2 on x86-linux, triggers a SEGV in the current mainline compiler, there: do_simple_structure_copy { ... for (; p && p->offset < last; p = p->next) { ... q = first_vi_for_offset (q, q->offset + fieldoffset); ==>temprhs.var = q->id; Below is a description of what is going on, plus suggestions on how to address the problem. I'd welcome feedback before submitting a patch with all the required testing process. The test basically constructs a record type with two 6bits long components, each of a record type also, and the two components (called key1 and key2) are tighly packed with a representation clause (no hole between the two components). Something like: 6bits 6bits |...|...| key1key2 Eventhough the field *decls* specify a 6bits length, the *type* of each is actually QI integer (8bits long). The SEGV above triggers on an assignment to a .key1 component from a standalone variable of the corresponding type. This is Keys.One_Pair.Key1 := Keys.One_Key; in k.adb. Several factors come into play, AFAICS: o the incoming 'size' argument is based on type and not decl information, and is used to bound the iteration (to compute 'last') o the offset increments for each component within the loop are based on decl size information o .key2 appears as a successor of .key1 in the lhs because they are part of the same outer object. We remain in the for loop after processing the assignment to .key1 because the decl size is strictly smaller than the type size, so 'last' is not reached, and there is a 'next' variable in sight. But then, we're out of the source standalone variable contents, so first_vi_for_offset returns null and we SEGV on the dereference. A very simple way to deal with this is to just 'break' out of the loop when 'q' happens to be null, with an appropriate comment briefly explaining how this could happen. Another way would be to compute the incoming 'size' argument from decl information when appropriate. This seems more involved at first sight. Thanks in advance for your help, Olivier -- $ gcc -c -O2 k.adb -- raised STORAGE_ERROR : stack overflow (or erroneous memory access) with Keys; procedure K is begin Keys.One_Pair.Key1 := Keys.One_Key; end; package Keys is Key_Size : constant := 6; type Key_Value_T is range 0 .. 2 ** Key_Size - 1; for Key_Value_T'Size use Key_Size; type Key_T is record Value : Key_Value_T; end record; for Key_T use record Value at 0 range 0 .. Key_Size - 1; end record; type Key_Pair_T is record Key1, Key2 : Key_T; end record; for Key_Pair_T use record Key1 at 0 range 0 .. Key_Size - 1; Key2 at 0 range Key_Size .. Key_Size + Key_Size - 1; end record; One_Key : Key_T := (Value => 1); One_Pair : Key_Pair_T; end;
Re: SEGV in do_simple_structure_copy
On Oct 6, 2005, at 12:00 PM, Olivier Hainque wrote: Hello, The Ada testcase below, compiled with -O2 on x86-linux, triggers a SEGV in the current mainline compiler, there: do_simple_structure_copy { ... for (; p && p->offset < last; p = p->next) { ... q = first_vi_for_offset (q, q->offset + fieldoffset); ==>temprhs.var = q->id; Below is a description of what is going on, plus suggestions on how to address the problem. I'd welcome feedback before submitting a patch with all the required testing process. The test basically constructs a record type with two 6bits long components, each of a record type also, and the two components (called key1 and key2) are tighly packed with a representation clause (no hole between the two components). Something like: 6bits 6bits |...|...| key1key2 Eventhough the field *decls* specify a 6bits length, the *type* of each is actually QI integer (8bits long). IOW, you are lying to the middle-end about the size of the fields. Why is the type not a 6 bit integer? A very simple way to deal with this is to just 'break' out of the loop when 'q' happens to be null, with an appropriate comment briefly explaining how this could happen. Except that it should never happen. We should never have a case where we've computed the sizes wrong, such that a simple structure copy fails. Simply breaking out of this loop will cause you erorrs later. Another way would be to compute the incoming 'size' argument from decl information when appropriate. This seems more involved at first sight. This is the correct fix, however, if you are going to lie to the middle end about TYPE_SIZE so that the TYPE_SIZE and DECL_SIZE do not match.
Re: SEGV in do_simple_structure_copy
Daniel Berlin wrote: > IOW, you are lying to the middle-end about the size of the fields. > Why is the type not a 6 bit integer? Because we avoid creating a different type for every possible bitsize, which seems to be the purpose of DECL_SIZE in the first place and is explicitly expected by the low-level story-layout circuitry: layout_decl (tree decl, unsigned int known_align) ... /* Usually the size and mode come from the data type without change, however, the front-end may set the explicit width of the field, so its size may not be the same as the size of its type. This happens with bitfields, of course (an `int' bitfield may be only 2 bits, say), but it also happens with other fields. The C front-end behaves similarily, creating external packed bit-field nonaddressable decl_4 QI file tt.c line 3 size unit size unit size align 8 symtab 0 alias set -1 precision 3 min max > for typedef struct __attribute__ ((packed)) { int x:3; > >Another way would be to compute the incoming 'size' argument from decl > >information when appropriate. This seems more involved at first sight. > > This is the correct fix, however, if you are going to lie to the > middle end about TYPE_SIZE so that the TYPE_SIZE and DECL_SIZE do not > match. Well, I'm actually not sure we have a choice. And I'm not sure it is really a lie. A restricted set of values happen to fit in a lower number of bits than what some type allows, it is not obvious that it makes those values of a different type. Thanks for your feedback. Olivier
Re: SEGV in do_simple_structure_copy
On Thu, Oct 06, 2005 at 10:22:08PM +0200, Olivier Hainque wrote: > Because we avoid creating a different type for every possible > bitsize... ... > The C front-end behaves similarily, creating ... > precision 3 min max > ^^^ Actually, we did create a different type just for this bitsize. Not that that detracts from the fact that TYPE_SIZE is always a multiple of BITS_PER_UNIT. r~
Re: SEGV in do_simple_structure_copy
On Oct 6, 2005, at 4:22 PM, Olivier Hainque wrote: Daniel Berlin wrote: IOW, you are lying to the middle-end about the size of the fields. Why is the type not a 6 bit integer? layout_decl (tree decl, unsigned int known_align) ... /* Usually the size and mode come from the data type without change, however, the front-end may set the explicit width of the field, so its size may not be the same as the size of its type. This happens with bitfields, of course (an `int' bitfield may be only 2 bits, say), but it also happens with other fields. The C front-end behaves similarily, creating external packed bit-field nonaddressable decl_4 QI file tt.c line 3 size unit size unit size align 8 symtab 0 alias set -1 precision 3 min max > You'll note we actually created a new type for this :) but anyway, This is the correct fix, however, if you are going to lie to the middle end about TYPE_SIZE so that the TYPE_SIZE and DECL_SIZE do not match. Well, I'm actually not sure we have a choice. And I'm not sure it is really a lie. A restricted set of values happen to fit in a lower number of bits than what some type allows, it is not obvious that it makes those values of a different type. Thinking harder about it, you might be better off then making everything based on TYPE_SIZE then, since we don't always have the FIELD_DECL's handy.
Re: Bug or feature: symbol names of global/extern variables
On Oct 6, 2005, at 2:44 AM, Michael Veksler wrote: This is the wrong list for linker enhancements. You should look for binutils mailing lists. However "collect2" which is part of gcc and is called before the linker (for C++)- could also detect this and give the same warning. I would bet that collect2 is the wrong place for this enhancement because it will work only for C++, not for C. This is wrong, collect2 is also used for C code.
gcc-4.0-20051006 is now available
Snapshot gcc-4.0-20051006 is now available on ftp://gcc.gnu.org/pub/gcc/snapshots/4.0-20051006/ and on various mirrors, see http://gcc.gnu.org/mirrors.html for details. This snapshot has been generated from the GCC 4.0 CVS branch with the following options: -rgcc-ss-4_0-20051006 You'll find: gcc-4.0-20051006.tar.bz2 Complete GCC (includes all of below) gcc-core-4.0-20051006.tar.bz2 C front end and core compiler gcc-ada-4.0-20051006.tar.bz2 Ada front end and runtime gcc-fortran-4.0-20051006.tar.bz2 Fortran front end and runtime gcc-g++-4.0-20051006.tar.bz2 C++ front end and runtime gcc-java-4.0-20051006.tar.bz2 Java front end and runtime gcc-objc-4.0-20051006.tar.bz2 Objective-C front end and runtime gcc-testsuite-4.0-20051006.tar.bz2The GCC testsuite Diffs from 4.0-20050929 are available in the diffs/ subdirectory. When a particular snapshot is ready for public consumption the LATEST-4.0 link is updated and a message is sent to the gcc list. Please do not use a snapshot before it has been announced that way.