https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91049

Martin Sebor <msebor at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
            Summary|wrong location in           |wrong location in
                   |-Wreturn-local-addr for a   |-Wreturn-local-addr for a
                   |return throw                |return with a conditional
                   |                            |expression

--- Comment #2 from Martin Sebor <msebor at gcc dot gnu.org> ---
I'm not sure this a middle-end issue.  The path isolation pass uses the
location of the return statement to issue the warning.  In C, the location is
that of the whole operand to the statement.  That also doesn't seem quite right
but it's less confusing than in C++ where the location corresponds to just one
of the operand (the second one?).  When the operand is not the address of a
local variable it's plain wrong.

The difference in the location between C and C++ can be seen as early as the
Gimple dump.  It only shows the beginning location so it's not complete but
it's the starting location that's the problem.  Here's C:

$ cat a.C && gcc -O2 -S -Wall -fdump-tree-gimple-lineno=/dev/stdout -xc a.C
void* g (int i)
{
  extern int j;
  return i ?
         &i :
         &j;
}

g (int i)
[a.C:2:1] {
  void * D.1913;
  int * iftmp.0;
  extern int j;

  [a.C:4:12] i.1_1 = i;
  [a.C:5:13] if (i.1_1 != 0) goto <D.1915>; else goto <D.1916>;
  <D.1915>:
  [a.C:5:13] iftmp.0 = [a.C:5:10] &i;
  goto <D.1917>;
  <D.1916>:
  [a.C:5:13] iftmp.0 = [a.C:6:10] &j;
  <D.1917>:
  [a.C:5:13] D.1913 = iftmp.0;
  [a.C:5:13] return D.1913;
}


a.C: In function ā€˜g’:
a.C:5:13: warning: function may return address of local variable
[-Wreturn-local-addr]
    4 |   return i ?
      |          ~~~ 
    5 |          &i :
      |          ~~~^
    6 |          &j;
      |          ~~  
a.C:1:14: note: declared here
    1 | void* g (int i)
      |          ~~~~^


and here's the dump for the same test case compiled as C++:

g (int i)
[a.C:6:12] {
  void * D.2304;
  int * iftmp.0;
  extern int j;

  [a.C:6:11] i.1_1 = i;
  [a.C:6:11] if (i.1_1 != 0) goto <D.2306>; else goto <D.2307>;
  <D.2306>:
  [a.C:6:11] iftmp.0 = [a.C:5:10] &i;
  goto <D.2308>;
  <D.2307>:
  [a.C:6:11] iftmp.0 = [a.C:6:10] &j;
  <D.2308>:
  [a.C:6:11] D.2304 = iftmp.0;
  [a.C:6:11] return D.2304;
}

Reply via email to