Bug 40635 - bogus name and location in 'may be used uninitialized' warning
Summary: bogus name and location in 'may be used uninitialized' warning
Status: NEW
Alias: None
Product: gcc
Classification: Unclassified
Component: tree-optimization (show other bugs)
Version: 4.4.1
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: diagnostic
Depends on:
Blocks: Wuninitialized
  Show dependency treegraph
 
Reported: 2009-07-03 12:09 UTC by Mikael Pettersson
Modified: 2013-12-19 10:59 UTC (History)
3 users (show)

See Also:
Host: i686-pc-linux-gnu
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2009-07-06 13:19:06


Attachments
main.c (759 bytes, text/x-csrc)
2013-12-19 10:57 UTC, philipp
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Mikael Pettersson 2009-07-03 12:09:26 UTC
The following test case produces a 'may be used uninitialized' warning that refers to a variable that isn't in scope at the point of the warning:

> cat nntpinit.c
struct hostent {
    char **h_addr_list;
};
struct hostent *gethostbyname(const char*);
int socket(void);
int close(int);
int connect(int, const char*);
void foo(void);

static int get_tcp_socket(const char *machine)
{
    struct hostent *hp;
    int s42, x;
    char **addr;

    hp = gethostbyname(machine);
    x = 0;
    for (addr = hp->h_addr_list; *addr; addr++) {
        s42 = socket();
        if (s42 < 0)
            return -1;
        x = connect(s42, *addr);
        if (x == 0)
            break;
        close(s42);
    }
    if (x < 0)
        return -1;
    return s42;
}

int server_init(const char *machine)
{
    int sockt_rd;

    sockt_rd = get_tcp_socket(machine);
    foo();
    if (sockt_rd < 0)
        return -1;
    return 0;
}
> gcc -O2 -Wall -c nntpinit.c
nntpinit.c: In function 'server_init':
nntpinit.c:38: warning: 's42' may be used uninitialized in this function

There is indeed a 'may be used uninitialized' issue in this code, but it's actually in get_tcp_socket(), not in server_init() because there every use is trivially preceeded by a def.

I guess that automatic inlining is messing up name and context information.

The test case is distilled down from some ancient nntp client code I'm tidying up, and the bogus data in the warning did cause some headscratching before the warning could be analysed and fixed (set x = -1 in get_tcp_socket()).
Comment 1 Antonio Weber 2009-07-05 10:29:48 UTC
I only wanted to confirm this report. The same behaviour with gcc 4.3.2 and a build from yesterdays svn

%> gcc -O2 -Wall -c ~/test.c
~/test.c: In function »server_init«:
~/test.c:38: warning: 's42' may be used uninitialized in this function

%> gcc --version
gcc (Gentoo 4.3.2-r3 p1.6, pie-10.1.5) 4.3.2
Copyright (C) 2008 Free Software Foundation, Inc.

%> ./bin/gcc -O2 -Wall -c ~/test.c
~/test.c: In function »server_init«:
~/test.c:38:8: warning: 's42' may be used uninitialized in this function

%> ./bin/gcc --version
gcc (GCC) 4.5.0 20090704 (experimental)
Copyright (C) 2009 Free Software Foundation, Inc.

Comment 2 Manuel López-Ibáñez 2009-07-06 13:19:01 UTC
The root cause is a combination of inline and copy-rename. Copy rename has the following code:

  /* Never attempt to coalesce 2 user variables unless one is an inline
     variable.  */
  if (!ign1 && !ign2)
    {
      if (DECL_FROM_INLINE (root2))
        ign2 = true;
      else if (DECL_FROM_INLINE (root1))
        ign1 = true;
      else
        {
          if (debug)
            fprintf (debug, " : 2 different USER vars. No coalesce.\n");
          return false;
        }
    }

  /* If both values have default defs, we can't coalesce.  If only one has a
     tag, make sure that variable is the new root partition.  */
  if (gimple_default_def (cfun, root1))
    {
      if (gimple_default_def (cfun, root2))
        {
          if (debug)
            fprintf (debug, " : 2 default defs. No coalesce.\n");
          return false;
        }
      else
        {
          ign2 = true;
          ign1 = false;
        }
    }
  else if (gimple_default_def (cfun, root2))
    {
      ign1 = true;
      ign2 = false;
    }

The net result is that when it combines sockt_rd with s42, it favours s42. This is the reason it prints s42. However, the location printed corresponds to the statement:

 if (sockt_rd < 0)
        return -1;



Then, warn_uninit is not able to detect that this comes from some inlined thing. If we do this:

-  location = (context != NULL && gimple_has_location (context))
+  location = (!DECL_FROM_INLINE (var) && context != NULL
+             && gimple_has_location (context))
             ? gimple_location (context)
-            : DECL_SOURCE_LOCATION (var);
+            : DECL_SOURCE_LOCATION (DECL_ORIGIN (var));

Then we get the right location (line, column) but still the wrong function. I am not sure how to force the diagnostics machinery to display the correct function.
Comment 3 Manuel López-Ibáñez 2013-11-01 21:56:08 UTC
This somehow got worse. Now we only warn with -O1 or -Os but not with -O2 or -O3.
Comment 4 philipp 2013-12-19 10:02:47 UTC
I have this or a very similar problem with debian amd64 4:4.8.2-1:

main.c: In function ‘main’:
main.c:1231:23: error: ‘rv’ may be used uninitialized in this function [-Werror=maybe-uninitialized]
  return (rv_main >= 0 && rv_main < 0x70) ? rv_main : 1;
Comment 5 Manuel López-Ibáñez 2013-12-19 10:17:51 UTC
(In reply to philipp from comment #4)
> I have this or a very similar problem with debian amd64 4:4.8.2-1:
> 
> main.c: In function ‘main’:
> main.c:1231:23: error: ‘rv’ may be used uninitialized in this function
> [-Werror=maybe-uninitialized]
>   return (rv_main >= 0 && rv_main < 0x70) ? rv_main : 1;

Can you attach a small, preprocessed testcase? See http://gcc.gnu.org/bugs/minimize.html
Comment 6 philipp 2013-12-19 10:40:26 UTC
I'm trying to get a minimized file via creduce.

In case you have an experienced guess please look at src/main.c from
   github.com:ClusterLabs/booth.git
   44b06e6d3c9c81d287020fe017a05f1386ae5e6e


Thanks.
Comment 7 Manuel López-Ibáñez 2013-12-19 10:51:44 UTC
(In reply to philipp from comment #6)
> I'm trying to get a minimized file via creduce.
> 
> In case you have an experienced guess please look at src/main.c from
>    github.com:ClusterLabs/booth.git
>    44b06e6d3c9c81d287020fe017a05f1386ae5e6e
> 
> 
> Thanks.

My guess is that it is exactly the same issue: inlining + variable coalescing. The inlining part could be improved, but variable coalescing seems a harder problem as long as we warn after coalescing (a unique name has to be chosen). See comment #2.
Comment 8 philipp 2013-12-19 10:56:41 UTC
I forgot to say that the uninitialized "rv" is in query_get_string_answer().

I've got a reduced main.c - but sadly there are still includes to other files, so it won't help that much.

I'll attach it here anyway.
Comment 9 philipp 2013-12-19 10:57:17 UTC
Created attachment 31480 [details]
main.c

not much use because of includes.
Comment 10 philipp 2013-12-19 10:59:03 UTC
Well, I've found the culprit, so it's not that important to me anymore.

Getting a completely wrong code location is the problem - you don't know what to fix, and have to do some kind of search.