I'm not clear whether this is a problem in GCC or in GDB, so I'm asking both teams. Compiling gdb 6.7.1 on Solaris 10 using the newly installed GCC 4.3.0, I got a compilation error (because of the -Werror option) as shown: gcc -c -g -O2 -I. -I.././gdb -I.././gdb/config -DLOCALEDIR="\"/usr/gdb/v6.7.1/share/locale\"" -DHAVE_CONFIG_H -I.././gdb/../include/opcode -I.././gdb/../readline/.. -I../bfd -I.././gdb/../bfd -I.././gdb/../include -I./../intl -DMI_OUT=1 -DTUI=1 -Wall -Wdeclaration-after-statement -Wpointer-arith -Wformat-nonliteral -Wno-pointer-sign -Wno-unused -Wno-switch -Wno-char-subscripts -Werror symtab.c cc1: warnings being treated as errors symtab.c: In function 'find_line_symtab': symtab.c:2252: error: 'exact' may be used uninitialized in this function make: *** [symtab.o] Error 1 The fragment in question was 'worked around' by adding the '= 0' to the declaration of 'exact' at: struct symtab * find_line_symtab (struct symtab *symtab, int line, int *index, int *exact_match) { int exact = 0; /* BEST_INDEX and BEST_LINETABLE identify the smallest linenumber > LINE so far seen. */ int best_index; struct linetable *best_linetable; struct symtab *best_symtab; /* First try looking it up in the given symtab. */ best_linetable = LINETABLE (symtab); best_symtab = symtab; best_index = find_line_common (best_linetable, line, &exact); if (best_index < 0 || !exact) { It is not clear to me that GCC is entitled to complain. However, given that it does, the workaround at least allows the compilation to proceed. The configure script for GDB was run as: ./configure --prefix=/usr/gdb/v6.7.1 The configure script for GCC was run as: ../gcc-4.3.0/configure --prefix=/usr/gcc/v4.3.0 --with-mpfr=/usr/gnu --with-gmp=/usr/gnu I don't suppose it matters, but the version of MPFR was 2.3.1, compiled using GCC 4.2.3, and the version of GMP was 4.1.2, which I apparently compiled a long time ago with GCC 3.3.2. The platform information from the GCC 4.2.0 config.log is: ## --------- ## ## Platform. ## ## --------- ## hostname = black uname -m = sun4u uname -r = 5.10 uname -s = SunOS uname -v = Generic_120011-14 /usr/bin/uname -p = sparc /bin/uname -X = System = SunOS Node = black Release = 5.10 KernelID = Generic_120011-14 Machine = sun4u BusType = <unknown> Serial = <unknown> Users = <unknown> OEM# = 0 Origin# = 1 NumCPU = 4 /bin/arch = sun4 /usr/bin/arch -k = sun4u /usr/convex/getsysinfo = unknown hostinfo = unknown /bin/machine = unknown /usr/bin/oslevel = unknown /bin/universe = unknown ...I don't see where to provide the symtab.i file; it is 427733 bytes long uncompressed (but just 68724 bytes long in a bzip2 file)... The information is available on request.
Created attachment 15294 [details] bzip2-compressed version of symtab.i (pre-processed code that triggered the bug report) This is the symtab.i file generated from the standard symtab.c (which omits the '= 0' intitializer on variable 'exact' compared with the code fragment shown in the bug report. It was sufficiently long since I last submitted a GCC bug that I didn't remember that this second screen showed up to give you a chance to upload files. It might be worth mentioning it on the bug entry page - unless it was and I missed it (in which case sorry).
I tried the following close-to-minimal reproduction - using the same compile command as for the original symtab.c problem - and did not get the error. struct symtab; struct linetable; extern int find_line_common(struct linetable *, int, int *); extern struct linetable *LINETABLE(struct symtab *); extern void do_something(void); struct symtab * find_line_symtab (struct symtab *symtab, int line, int *index, int *exact_match) { int exact /* = 0 */; /* BEST_INDEX and BEST_LINETABLE identify the smallest linenumber > LINE so far seen. */ int best_index; struct linetable *best_linetable; struct symtab *best_symtab; /* First try looking it up in the given symtab. */ best_linetable = LINETABLE (symtab); best_symtab = symtab; best_index = find_line_common (best_linetable, line, &exact); if (best_index < 0 || !exact) { do_something(); } return(best_symtab); }
The important part is: best_index = find_line_common (best_linetable, line, &exact); how is find_line_common defined. Does it set exact on every code path? If not then is it on every code path where the return value is greater than 0? -- Pinski
So looking at the code, I see that we have a loop that might return the loop variant. Now we should be able to prove this loop variant is greater than or equal 0 but we don't. Really this is just a false positive warning though hard to prove without going through the code checking out all code paths.
After a 'mid-air collision': The code for find_line_common() is in the same file, later on, but declared static, so GCC can analyze it -- and then it is correct to complain: static int find_line_common (struct linetable *l, int lineno, int *exact_match) { int i; int len; /* BEST is the smallest linenumber > LINENO so far seen, or 0 if none has been seen so far. BEST_INDEX identifies the item for it. */ int best_index = -1; int best = 0; if (lineno <= 0) return -1; if (l == 0) return -1; len = l->nitems; for (i = 0; i < len; i++) { struct linetable_entry *item = &(l->item[i]); if (item->line == lineno) { /* Return the first (lowest address) entry which matches. */ *exact_match = 1; return i; } if (item->line > lineno && (best == 0 || item->line < best)) { best = item->line; best_index = i; } } /* If we got here, we didn't get an exact match. */ *exact_match = 0; return best_index; } The two early exits do leave exact unset. However, those cases leave best_index in find_line_symtab less than zero, so the test would not access exact in those cases. It is a bit hard for GCC to note that for all other return cases, the returned value assigned to best_index is non-negative and that exact is then set.
(In reply to comment #4) > So looking at the code, I see that we have a loop that might return the loop > variant. Now we should be able to prove this loop variant is greater than or > equal 0 but we don't. Really this is just a false positive warning though hard > to prove without going through the code checking out all code paths. Thank you for the prompt feedback. I can see that it is most probably very difficult to prove that the false positive is false. However, from the GDB team's point of view, their code was working previously and the new compiler is causing working code to be rejected - which is irksome, especially as it is a false positive. I'm not sure what to recommend. As I said, I've worked around it by modifying the GDB source code, but that isn't ideal. Also, I'd appreciate advice on what, if anything, to tell the GDB team.
Subject: Re: Problem compiling gdb/symtab.c in GDB 6.7.1 using GCC 4.3.0 on Solaris 10 Sent from my iPhone On Mar 10, 2008, at 21:23, "jonathan dot leffler at gmail dot com" <gcc-bugzilla@gcc.gnu.org > wrote: > > > ------- Comment #6 from jonathan dot leffler at gmail dot com > 2008-03-11 04:23 ------- > I'm not sure what to recommend. As I said, I've worked around it by > modifying > the GDB source code, but that isn't ideal. Also, I'd appreciate > advice on > what, if anything, to tell the GDB team. The thing to check is if this code has already been changed in the trunk of GDB. I think it already has. Thanks, Andrew Pinski
CVS tree of v6.8 collected from "cvs -d :pserver:anoncvs@sourceware.org:/cvs/src co -r gdb_6_8-branch gdb" shows that the current code does indeed include *exact_match = 0; early in the find_line_common() function, so that it would not trigger the warning. The latest release code is 6.7.1 - so the problem occurs in the latest released code, but has been fixed in the current development version. I will relay this to GDB team (basically to stand them down). It appears that GCC team can close this bug. OK - I've closed it as INVALID; I guess that is the correct resolution from the GCC point of view. Sorry to be a trouble - glad it doesn't involve code changes. Not sure that I'd've deduced the problem without the guidance.
Subject: Re: New: Problem compiling gdb/symtab.c in GDB 6.7.1 using GCC 4.3.0 on Solaris 10 jonathan dot leffler at gmail dot com wrote: > The fragment in question was 'worked around' by adding the '= 0' to the > declaration of 'exact' at: This is really just a warning. It only causes the build to fail because gdb uses -Werror to turn warnings into errors. You can simply configure gdb with --disable-werror, there's no need to edit anything. It should probably be actually fixed at some point (as that's the whole point of turning warnings into errors, to force attention), but these kind of things happen fairly often and that's why there's a --disable-werror.