Bug 35534 - Problem compiling gdb/symtab.c in GDB 6.7.1 using GCC 4.3.0 on Solaris 10
Summary: Problem compiling gdb/symtab.c in GDB 6.7.1 using GCC 4.3.0 on Solaris 10
Status: RESOLVED INVALID
Alias: None
Product: gcc
Classification: Unclassified
Component: middle-end (show other bugs)
Version: 4.3.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2008-03-11 03:35 UTC by Jonathan Leffler
Modified: 2008-03-11 06:55 UTC (History)
2 users (show)

See Also:
Host: sparc-sun-solaris2.10
Target: sparc-sun-solaris2.10
Build: sparc-sun-solaris2.10
Known to work:
Known to fail:
Last reconfirmed:


Attachments
bzip2-compressed version of symtab.i (pre-processed code that triggered the bug report) (66.67 KB, application/octet-stream)
2008-03-11 03:39 UTC, Jonathan Leffler
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Jonathan Leffler 2008-03-11 03:35:39 UTC
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.
Comment 1 Jonathan Leffler 2008-03-11 03:39:13 UTC
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).
Comment 2 Jonathan Leffler 2008-03-11 03:48:27 UTC
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);
}
Comment 3 Andrew Pinski 2008-03-11 03:54:24 UTC
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
Comment 4 Andrew Pinski 2008-03-11 04:00:35 UTC
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.
Comment 5 Jonathan Leffler 2008-03-11 04:04:03 UTC
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.

Comment 6 Jonathan Leffler 2008-03-11 04:23:33 UTC
(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.

Comment 7 pinskia@gmail.com 2008-03-11 04:53:43 UTC
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
Comment 8 Jonathan Leffler 2008-03-11 06:55:07 UTC
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.
Comment 9 brian 2008-03-11 08:58:55 UTC
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.