Bug 45821

Summary: Missed -Wreturn-local-addr when local variable address comes from within a statement expression
Product: gcc Reporter: Andrew Gaul <gcc>
Component: cAssignee: Not yet assigned to anyone <unassigned>
Status: NEW ---    
Severity: minor CC: dmalcolm, dodji, egallager, manu, philiprbrenan
Priority: P3 Keywords: diagnostic, stmt-expr
Version: unknown   
Target Milestone: ---   
Host: Target:
Build: Known to work:
Known to fail: Last reconfirmed: 2015-09-18 00:00:00
Bug Depends on: 60517    
Bug Blocks: 772, 90556    
Attachments: example of bug
example of bug 2
example of bug 3

Description Andrew Gaul 2010-09-28 17:45:37 UTC
Created attachment 21904 [details]
example of bug

GCC warns when returning a local variable address within a function but not within a statement expression.
Comment 1 Andrew Gaul 2010-09-28 17:48:24 UTC
Created attachment 21905 [details]
example of bug 2
Comment 2 Andrew Gaul 2010-09-28 17:50:02 UTC
Created attachment 21906 [details]
example of bug 3
Comment 3 Andrew Gaul 2010-09-28 17:51:21 UTC
The web form truncates all my attachedments at 244 bytes.  Here is the source inline:

/*
 * GCC warns about returning a local variable address within a function but not
 * within a statement expression:
 *
 * $ gcc statement_expression_return_local.c -c -Wall
 * statement_expression_return_local.c: In function ‘function_return_local’:
 * statement_expression_return_local.c:13: warning: function returns address of local variable
 */

int *function_return_local(void)
{
    int x = 0;
    return &x;
}

int *statement_expression_return_local(void)
{
    int *y = ({
        int x = 0;
        &x;
    });
    return y;
}
Comment 4 Manuel López-Ibáñez 2015-09-18 00:04:35 UTC
(In reply to Andrew Gaul from comment #3)
> int *function_return_local(void)
> {
>     int x = 0;
>     return &x;
> }
> 
> int *statement_expression_return_local(void)
> {
>     int *y = ({
>         int x = 0;
>         &x;
>     });
>     return y;
> }

We now warn at -O2:

test.c:14:10: warning: function returns address of local variable [-Wreturn-local-addr]
   return y;
          ^
test.c:11:11: note: declared here
       int x = 0;
           ^

but only because we return y. For this testcase,

int statement_expression_return_local(void)
{
    int *y = ({
        int x = 0;
        &x;
    });
    return *y;
}

we get: 

test.c:14:10: warning: ‘x’ is used uninitialized in this function [-Wuninitialized]
   return *y;
          ^

which is a bit confusing (and not the same warning).

Possibly related to 60517.
it would be good to add the testcase
Comment 5 Eric Gallager 2018-07-28 03:23:14 UTC
cc-ing diagnostic messages maintainers
Comment 6 Eric Gallager 2019-10-28 04:06:17 UTC
(In reply to Manuel López-Ibáñez from comment #4)
> (In reply to Andrew Gaul from comment #3)
> > int *function_return_local(void)
> > {
> >     int x = 0;
> >     return &x;
> > }
> > 
> > int *statement_expression_return_local(void)
> > {
> >     int *y = ({
> >         int x = 0;
> >         &x;
> >     });
> >     return y;
> > }
> 
> We now warn at -O2:
> 
> test.c:14:10: warning: function returns address of local variable
> [-Wreturn-local-addr]
>    return y;
>           ^
> test.c:11:11: note: declared here
>        int x = 0;
>            ^
> 
> but only because we return y. For this testcase,
> 
> int statement_expression_return_local(void)
> {
>     int *y = ({
>         int x = 0;
>         &x;
>     });
>     return *y;
> }
> 
> we get: 
> 
> test.c:14:10: warning: ‘x’ is used uninitialized in this function
> [-Wuninitialized]
>    return *y;
>           ^
> 
> which is a bit confusing (and not the same warning).

It'd be good to get it from the same warning, so I'm making this block the -Wreturn-local-addr meta-bug

> 
> Possibly related to 60517.
> it would be good to add the testcase
Comment 7 Philip R Brenan 2020-10-28 14:26:57 UTC
A more compact example:

#include <stdio.h>
int * aaa() {return ({int a = 2;        &a;});} // no warning unless -O2
int * bbb() {         int b = 3; return &b;}    //    warning

int main(void)
 {int *a = aaa(), *b = bbb();
  fprintf(stderr, "AAAA %d\n", *a);
  fprintf(stderr, "BBBB %d\n", *b);
  return 0;
 }
// AAAA 3
// Segmentation fault (core dumped)

Please provide the warning for line 2 (aaa) regardless of the level of optimization?