public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c++/56568] New: std::initializer_list return value contents lost prematurely
@ 2013-03-08  8:40 potswa at mac dot com
  2015-09-03 21:41 ` [Bug c++/56568] " fuzzyTew at gmail dot com
                   ` (5 more replies)
  0 siblings, 6 replies; 7+ messages in thread
From: potswa at mac dot com @ 2013-03-08  8:40 UTC (permalink / raw)
  To: gcc-bugs


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

             Bug #: 56568
           Summary: std::initializer_list return value contents lost
                    prematurely
    Classification: Unclassified
           Product: gcc
           Version: 4.8.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
        AssignedTo: unassigned@gcc.gnu.org
        ReportedBy: potswa@mac.com


See http://stackoverflow.com/q/15286450/153285

This program segfaults:

#include <string>
#include <iostream>
#include <initializer_list>

int main() {
    for ( auto && s : []() -> std::initializer_list< std::string >
          { return { std::string( "first" ), std::string( "second" ) }; }() )
        std::cout << s << '\n';
}

The return value object should be initialized from the braced-init-list, and
bound directly to the implicit "auto && __range" object of the range-based for
statement. The array backing that object should have the same lifetime as it,
namely the duration of the loop. Instead, the array is destroyed when the
lambda exits.

This is not easy to fix, but I'll just file this.


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

* [Bug c++/56568] std::initializer_list return value contents lost prematurely
  2013-03-08  8:40 [Bug c++/56568] New: std::initializer_list return value contents lost prematurely potswa at mac dot com
@ 2015-09-03 21:41 ` fuzzyTew at gmail dot com
  2015-09-03 21:49 ` redi at gcc dot gnu.org
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: fuzzyTew at gmail dot com @ 2015-09-03 21:41 UTC (permalink / raw)
  To: gcc-bugs

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

fuzzyTew at gmail dot com changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |fuzzyTew at gmail dot com

--- Comment #1 from fuzzyTew at gmail dot com ---
Here's an example I ran into using a plain int:
http://coliru.stacked-crooked.com/a/1dfad4e209339aa1


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

* [Bug c++/56568] std::initializer_list return value contents lost prematurely
  2013-03-08  8:40 [Bug c++/56568] New: std::initializer_list return value contents lost prematurely potswa at mac dot com
  2015-09-03 21:41 ` [Bug c++/56568] " fuzzyTew at gmail dot com
@ 2015-09-03 21:49 ` redi at gcc dot gnu.org
  2015-09-03 23:51 ` fuzzyTew at gmail dot com
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: redi at gcc dot gnu.org @ 2015-09-03 21:49 UTC (permalink / raw)
  To: gcc-bugs

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

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

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |RESOLVED
         Resolution|---                         |INVALID

--- Comment #2 from Jonathan Wakely <redi at gcc dot gnu.org> ---
(In reply to fuzzyTew from comment #1)
> Here's an example I ran into using a plain int:
> http://coliru.stacked-crooked.com/a/1dfad4e209339aa1

That's undefined behaviour. You create a temporary array with one element, then
return an initializer_list which is bound to that local array, which goes out
of scope.

Your example and the original testcase are equivalent to:

const int& f() {
  long i = 0;
  return i;
}

which creates a temporary and binds a reference to it, resulting in a dangling
reference.

std::initializer_list is not a container, don't try to do clever things with
it, you will get burnt.


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

* [Bug c++/56568] std::initializer_list return value contents lost prematurely
  2013-03-08  8:40 [Bug c++/56568] New: std::initializer_list return value contents lost prematurely potswa at mac dot com
  2015-09-03 21:41 ` [Bug c++/56568] " fuzzyTew at gmail dot com
  2015-09-03 21:49 ` redi at gcc dot gnu.org
@ 2015-09-03 23:51 ` fuzzyTew at gmail dot com
  2015-09-03 23:53 ` fuzzyTew at gmail dot com
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: fuzzyTew at gmail dot com @ 2015-09-03 23:51 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #3 from fuzzyTew at gmail dot com ---
The definition of initializer_list is that the array backing it contains copies
of the listed values and has the same lifetime as the list itself.

If the return value is bound into the object assigned to it, the backing array
should stick around as long as the return value does.


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

* [Bug c++/56568] std::initializer_list return value contents lost prematurely
  2013-03-08  8:40 [Bug c++/56568] New: std::initializer_list return value contents lost prematurely potswa at mac dot com
                   ` (2 preceding siblings ...)
  2015-09-03 23:51 ` fuzzyTew at gmail dot com
@ 2015-09-03 23:53 ` fuzzyTew at gmail dot com
  2015-09-04  0:25 ` potswa at mac dot com
  2015-09-04  9:02 ` redi at gcc dot gnu.org
  5 siblings, 0 replies; 7+ messages in thread
From: fuzzyTew at gmail dot com @ 2015-09-03 23:53 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #4 from fuzzyTew at gmail dot com ---
I'm not as experienced in the details.  I think perhaps my example is invalid
as you state but the original testcase is not (see &&).


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

* [Bug c++/56568] std::initializer_list return value contents lost prematurely
  2013-03-08  8:40 [Bug c++/56568] New: std::initializer_list return value contents lost prematurely potswa at mac dot com
                   ` (3 preceding siblings ...)
  2015-09-03 23:53 ` fuzzyTew at gmail dot com
@ 2015-09-04  0:25 ` potswa at mac dot com
  2015-09-04  9:02 ` redi at gcc dot gnu.org
  5 siblings, 0 replies; 7+ messages in thread
From: potswa at mac dot com @ 2015-09-04  0:25 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #5 from David Krauss <potswa at mac dot com> ---
(In reply to fuzzyTew from comment #4)

The original testcase is invalid. initializer_list is special in that it
behaves like a reference, so adding && doesn't make a difference.

I'm working on an ISO proposal (http://bit.ly/genlife) to fix some such cases
in C++17, but all it would do for return values is allow the compiler to
produce a warning. The way initializer_list works, the sequence is
intrinsically incapable of escaping the current scope, much less the current
function.


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

* [Bug c++/56568] std::initializer_list return value contents lost prematurely
  2013-03-08  8:40 [Bug c++/56568] New: std::initializer_list return value contents lost prematurely potswa at mac dot com
                   ` (4 preceding siblings ...)
  2015-09-04  0:25 ` potswa at mac dot com
@ 2015-09-04  9:02 ` redi at gcc dot gnu.org
  5 siblings, 0 replies; 7+ messages in thread
From: redi at gcc dot gnu.org @ 2015-09-04  9:02 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #6 from Jonathan Wakely <redi at gcc dot gnu.org> ---
(In reply to fuzzyTew from comment #4)
> I'm not as experienced in the details.  I think perhaps my example is
> invalid as you state but the original testcase is not (see &&).

That makes no difference. Using my previous example, David's original testcase
is roughly equivalent to:

const int& f() {
  long i = 0;
  return i;
}

auto&& i = f();

It's irrelevant what you do with the result, f() returns a dangling reference
to an object that doesn't exist after the function returns.


(In reply to David Krauss from comment #5)
> I'm working on an ISO proposal (http://bit.ly/genlife) to fix some such
> cases in C++17, but all it would do for return values is allow the compiler
> to produce a warning. The way initializer_list works, the sequence is
> intrinsically incapable of escaping the current scope, much less the current
> function.

Right.

I opened PR 67445 to suggest a warning for cases like this, but I don't expect
it to be implemented any time soon.


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

end of thread, other threads:[~2015-09-04  9:02 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-03-08  8:40 [Bug c++/56568] New: std::initializer_list return value contents lost prematurely potswa at mac dot com
2015-09-03 21:41 ` [Bug c++/56568] " fuzzyTew at gmail dot com
2015-09-03 21:49 ` redi at gcc dot gnu.org
2015-09-03 23:51 ` fuzzyTew at gmail dot com
2015-09-03 23:53 ` fuzzyTew at gmail dot com
2015-09-04  0:25 ` potswa at mac dot com
2015-09-04  9:02 ` redi 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).