public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c++/49974] New: missing warning for indirectly returning reference to local/temporary
@ 2011-08-04 12:23 redi at gcc dot gnu.org
  2011-08-04 12:29 ` [Bug c++/49974] " manu at gcc dot gnu.org
                   ` (9 more replies)
  0 siblings, 10 replies; 11+ messages in thread
From: redi at gcc dot gnu.org @ 2011-08-04 12:23 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49974

           Summary: missing warning for indirectly returning reference to
                    local/temporary
           Product: gcc
           Version: 4.7.0
            Status: UNCONFIRMED
          Keywords: diagnostic
          Severity: normal
          Priority: P3
         Component: c++
        AssignedTo: unassigned@gcc.gnu.org
        ReportedBy: redi@gcc.gnu.org


Although probably not easy, it would be useful to get warnings from this code
which creates dangling references:

struct X { };

inline const X& f(const X& r) { return r; }

const X& g()
{
    X x;
    return f(x);  // !!!
}

const X& h()
{
    return f(X()); // !!!
}

Another case involves a reference as a member of a class:

struct Y {
    Y(int& i) : r(i) { }
    int& r;
};

Y f()
{
    int i=0;
    return Y(i);
}


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug c++/49974] missing warning for indirectly returning reference to local/temporary
  2011-08-04 12:23 [Bug c++/49974] New: missing warning for indirectly returning reference to local/temporary redi at gcc dot gnu.org
@ 2011-08-04 12:29 ` manu at gcc dot gnu.org
  2011-08-04 12:40 ` redi at gcc dot gnu.org
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: manu at gcc dot gnu.org @ 2011-08-04 12:29 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49974

Manuel López-Ibáñez <manu at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |manu at gcc dot gnu.org

--- Comment #1 from Manuel López-Ibáñez <manu at gcc dot gnu.org> 2011-08-04 12:29:21 UTC ---
Isn't this related to PR986?


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug c++/49974] missing warning for indirectly returning reference to local/temporary
  2011-08-04 12:23 [Bug c++/49974] New: missing warning for indirectly returning reference to local/temporary redi at gcc dot gnu.org
  2011-08-04 12:29 ` [Bug c++/49974] " manu at gcc dot gnu.org
@ 2011-08-04 12:40 ` redi at gcc dot gnu.org
  2011-08-04 12:49 ` rguenth at gcc dot gnu.org
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: redi at gcc dot gnu.org @ 2011-08-04 12:40 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49974

Jonathan Wakely <redi at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Severity|normal                      |enhancement

--- Comment #2 from Jonathan Wakely <redi at gcc dot gnu.org> 2011-08-04 12:40:15 UTC ---
Maybe related, but not the same.  PR986 involves creating a temporary and
binding the reference to it, that should be easier to warn about.  Here's a
similar case to PR986 where a reference member is dangling after the
constructor, which we fail to warn about:

struct Y {
    Y(int local) : ref(local) { }
    int& ref;
};

That, and the example in 986, should be easy to warn about.  When the reference
is bound we can know if the initializer is local/temporary.

This PR is different, the references passed to f and Y::Y are valid during
those calls. The reference only becomes invalid when it escapes from the
function that declares the local variable.  This requires some more complex
analysis, only possible if the bodies of f and Y::Y are visible, and maybe only
possible with optimization enabled so inlining happens.


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug c++/49974] missing warning for indirectly returning reference to local/temporary
  2011-08-04 12:23 [Bug c++/49974] New: missing warning for indirectly returning reference to local/temporary redi at gcc dot gnu.org
  2011-08-04 12:29 ` [Bug c++/49974] " manu at gcc dot gnu.org
  2011-08-04 12:40 ` redi at gcc dot gnu.org
@ 2011-08-04 12:49 ` rguenth at gcc dot gnu.org
  2012-04-08 18:15 ` redi at gcc dot gnu.org
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: rguenth at gcc dot gnu.org @ 2011-08-04 12:49 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49974

Richard Guenther <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |NEW
   Last reconfirmed|                            |2011.08.04 12:48:48
     Ever Confirmed|0                           |1

--- Comment #3 from Richard Guenther <rguenth at gcc dot gnu.org> 2011-08-04 12:48:48 UTC ---
You could try to rely on points-to information.  When it says that all possible
pointees are automatic variable it's for sure an error (or a points-to bug).


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug c++/49974] missing warning for indirectly returning reference to local/temporary
  2011-08-04 12:23 [Bug c++/49974] New: missing warning for indirectly returning reference to local/temporary redi at gcc dot gnu.org
                   ` (2 preceding siblings ...)
  2011-08-04 12:49 ` rguenth at gcc dot gnu.org
@ 2012-04-08 18:15 ` redi at gcc dot gnu.org
  2013-06-05 18:26 ` paolo.carlini at oracle dot com
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: redi at gcc dot gnu.org @ 2012-04-08 18:15 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49974

--- Comment #4 from Jonathan Wakely <redi at gcc dot gnu.org> 2012-04-08 18:15:04 UTC ---
As pointed out in PR 52901 comment 3, this missing warning is likely to bite
people misusing std::move like so:

X&& f()
{
  X x;
  return std::move(x);
}


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug c++/49974] missing warning for indirectly returning reference to local/temporary
  2011-08-04 12:23 [Bug c++/49974] New: missing warning for indirectly returning reference to local/temporary redi at gcc dot gnu.org
                   ` (3 preceding siblings ...)
  2012-04-08 18:15 ` redi at gcc dot gnu.org
@ 2013-06-05 18:26 ` paolo.carlini at oracle dot com
  2020-06-26 13:48 ` [Bug c++/49974] missing -Wreturn-local-addr " redi at gcc dot gnu.org
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: paolo.carlini at oracle dot com @ 2013-06-05 18:26 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49974

Paolo Carlini <paolo.carlini at oracle dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |jewillco at osl dot iu.edu

--- Comment #5 from Paolo Carlini <paolo.carlini at oracle dot com> ---
*** Bug 57528 has been marked as a duplicate of this bug. ***


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug c++/49974] missing -Wreturn-local-addr for indirectly returning reference to local/temporary
  2011-08-04 12:23 [Bug c++/49974] New: missing warning for indirectly returning reference to local/temporary redi at gcc dot gnu.org
                   ` (4 preceding siblings ...)
  2013-06-05 18:26 ` paolo.carlini at oracle dot com
@ 2020-06-26 13:48 ` redi at gcc dot gnu.org
  2020-06-26 13:54 ` redi at gcc dot gnu.org
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: redi at gcc dot gnu.org @ 2020-06-26 13:48 UTC (permalink / raw)
  To: gcc-bugs

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

Jonathan Wakely <redi at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |570070308 at qq dot com

--- Comment #16 from Jonathan Wakely <redi at gcc dot gnu.org> ---
*** Bug 95911 has been marked as a duplicate of this bug. ***

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug c++/49974] missing -Wreturn-local-addr for indirectly returning reference to local/temporary
  2011-08-04 12:23 [Bug c++/49974] New: missing warning for indirectly returning reference to local/temporary redi at gcc dot gnu.org
                   ` (5 preceding siblings ...)
  2020-06-26 13:48 ` [Bug c++/49974] missing -Wreturn-local-addr " redi at gcc dot gnu.org
@ 2020-06-26 13:54 ` redi at gcc dot gnu.org
  2022-01-16  0:37 ` msebor at gcc dot gnu.org
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: redi at gcc dot gnu.org @ 2020-06-26 13:54 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #17 from Jonathan Wakely <redi at gcc dot gnu.org> ---
95911 boils down to this:

#include <utility>

struct X { int i = 0; };

X&& f(X&& x) { return std::move(x); }

int main()
{
  X&& x = f(X{});
  return x.i;
}

With recent releases we get a -Wuninitialized warning, which isn't entirely
correct, but at least suggests a problem:

49974.cc: In function 'int main()':
49974.cc:10:12: warning: '<anonymous>.X::i' is used uninitialized
[-Wuninitialized]
   10 |   return x.i;
      |            ^
49974.cc:9:15: note: '<anonymous>' declared here
    9 |   X&& x = f(X{});
      |               ^

(the note is new in GCC 11).

With -fsanitize=address we get a nice stack-use-after-scope error:

==3088273==ERROR: AddressSanitizer: stack-use-after-scope on address
0x7fff976ed520 at pc 0x000000401100 bp 0x7fff976ed4f0 sp 0x7fff976ed4e8
READ of size 4 at 0x7fff976ed520 thread T0
    #0 0x4010ff in main /tmp/49974.cc:10
    #1 0x7fd157d181a2 in __libc_start_main ../csu/libc-start.c:308
    #2 0x40116d in _start (/tmp/a.out+0x40116d)

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug c++/49974] missing -Wreturn-local-addr for indirectly returning reference to local/temporary
  2011-08-04 12:23 [Bug c++/49974] New: missing warning for indirectly returning reference to local/temporary redi at gcc dot gnu.org
                   ` (6 preceding siblings ...)
  2020-06-26 13:54 ` redi at gcc dot gnu.org
@ 2022-01-16  0:37 ` msebor at gcc dot gnu.org
  2024-02-15 18:39 ` barry.revzin at gmail dot com
  2024-02-15 18:44 ` pinskia at gcc dot gnu.org
  9 siblings, 0 replies; 11+ messages in thread
From: msebor at gcc dot gnu.org @ 2022-01-16  0:37 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #18 from Martin Sebor <msebor at gcc dot gnu.org> ---
This detection is partially implemented in GCC 12 by the -Wdnagling-pointer:

$ cat pr49974.C && gcc -O -S -Wall pr49974.C

struct X { };

inline const X& f(const X& r) { return r; }

const X& g()
{
    X x;
    return f(x);  // !!!
}

const X& h()
{
    return f(X()); // !!!
}


struct Y {
    Y(int& i) : r(i) { }
    int& r;
};

Y f()
{
    int i=0;
    return Y(i);
}
pr49974.C: In function ‘const X& g()’:
pr49974.C:9:15: warning: using a dangling pointer to ‘x’ [-Wdangling-pointer=]
    9 |     return f(x);  // !!!
      |               ^
pr49974.C:8:7: note: ‘x’ declared here
    8 |     X x;
      |       ^
pr49974.C: In function ‘const X& h()’:
pr49974.C:14:17: warning: using a dangling pointer to an unnamed temporary
[-Wdangling-pointer=]
   14 |     return f(X()); // !!!
      |                 ^
pr49974.C:14:16: note: unnamed temporary defined here
   14 |     return f(X()); // !!!
      |                ^


For the test case in comment #17 GCC with -O1 issues:

pr49974-c17.C: In function ‘int main()’:
pr49974-c17.C:11:12: warning: using a dangling pointer to an unnamed temporary
[-Wdangling-pointer=]
   11 |   return x.i;
      |            ^
pr49974-c17.C:10:15: note: unnamed temporary defined here
   10 |   X&& x = f(X{});
      |               ^
pr49974-c17.C:11:12: warning: ‘<anonymous>.X::i’ is used uninitialized
[-Wuninitialized]
   11 |   return x.i;
      |            ^
pr49974-c17.C:10:15: note: ‘<anonymous>’ declared here
   10 |   X&& x = f(X{});
      |               ^

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug c++/49974] missing -Wreturn-local-addr for indirectly returning reference to local/temporary
  2011-08-04 12:23 [Bug c++/49974] New: missing warning for indirectly returning reference to local/temporary redi at gcc dot gnu.org
                   ` (7 preceding siblings ...)
  2022-01-16  0:37 ` msebor at gcc dot gnu.org
@ 2024-02-15 18:39 ` barry.revzin at gmail dot com
  2024-02-15 18:44 ` pinskia at gcc dot gnu.org
  9 siblings, 0 replies; 11+ messages in thread
From: barry.revzin at gmail dot com @ 2024-02-15 18:39 UTC (permalink / raw)
  To: gcc-bugs

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

Barry Revzin <barry.revzin at gmail dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |barry.revzin at gmail dot com

--- Comment #19 from Barry Revzin <barry.revzin at gmail dot com> ---
Another example of this:

int get();

int const& f() {
    int const r = get();
    return r;
}

int const& g() {
    int const& r = get();
    return r;
}

gcc trunk warns on the incorrect use in f, but it does not currently warn on
the incorrect use in g (which is the exact same bug). clang warns on both.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug c++/49974] missing -Wreturn-local-addr for indirectly returning reference to local/temporary
  2011-08-04 12:23 [Bug c++/49974] New: missing warning for indirectly returning reference to local/temporary redi at gcc dot gnu.org
                   ` (8 preceding siblings ...)
  2024-02-15 18:39 ` barry.revzin at gmail dot com
@ 2024-02-15 18:44 ` pinskia at gcc dot gnu.org
  9 siblings, 0 replies; 11+ messages in thread
From: pinskia at gcc dot gnu.org @ 2024-02-15 18:44 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #20 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
(In reply to Barry Revzin from comment #19)
> Another example of this:
> 
> int get();
> 
> int const& f() {
>     int const r = get();
>     return r;
> }
> 
> int const& g() {
>     int const& r = get();
>     return r;
> }
> 
> gcc trunk warns on the incorrect use in f, but it does not currently warn on
> the incorrect use in g (which is the exact same bug). clang warns on both.

GCC trunk does warn on g but only with optimizations turned on.

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2024-02-15 18:44 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-08-04 12:23 [Bug c++/49974] New: missing warning for indirectly returning reference to local/temporary redi at gcc dot gnu.org
2011-08-04 12:29 ` [Bug c++/49974] " manu at gcc dot gnu.org
2011-08-04 12:40 ` redi at gcc dot gnu.org
2011-08-04 12:49 ` rguenth at gcc dot gnu.org
2012-04-08 18:15 ` redi at gcc dot gnu.org
2013-06-05 18:26 ` paolo.carlini at oracle dot com
2020-06-26 13:48 ` [Bug c++/49974] missing -Wreturn-local-addr " redi at gcc dot gnu.org
2020-06-26 13:54 ` redi at gcc dot gnu.org
2022-01-16  0:37 ` msebor at gcc dot gnu.org
2024-02-15 18:39 ` barry.revzin at gmail dot com
2024-02-15 18:44 ` pinskia at gcc dot gnu.org

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).