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

            Bug ID: 64329
           Summary: Crash when returning reference from lambda with
                    deduced type
           Product: gcc
           Version: 4.9.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: will at benfold dot com

Created attachment 34289
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=34289&action=edit
Preprocessed source

I believe the program below is valid and correct, but I see heap corruption at
the end of main() (in  std::map::~map) when I allow the compiler to deduce
return type of the lambda. 

Both the parameters to apply() are still alive when the returned lambda is
invoked, so fn(arg) should safely return a valid const ref to a tuple.  If the
return type for the lambda is given explicitly (see comments in code) then
everything is fine, whether it's returning by value or by const ref.

Compiling with "-Wall --std=c++11 -O0 -g3"; optimisation level seems to make no
difference.

----------------------------------------------------------------

#include <functional>
#include <map>
#include <string>
#include <tuple>

typedef std::tuple<std::string, std::string, double> Result;
typedef std::map<int, Result> Argument;
typedef std::function<const Result & (const Argument &)> Function;

std::function<Result ()> apply (const Argument &arg, const Function &fn)
{
  //  No trouble with any of these...
  //  return [&fn, &arg]() -> Result          { return fn(arg); };
  //  return [&fn, &arg]() -> const Result &  { return fn(arg); };
  //  return [&fn, &arg]()                    { Result r = fn(arg); return r;
};

  //  But this causes heap corruption
      return [&fn, &arg]()                    { return fn(arg); };
}

const Result &func (const Argument &arg)
{
  //  std::map::at returns a const ref
  return arg.at(0);
}

int main (int argc, char *argv[])
{
  Argument arg;
  arg[0] = Result("", "a", 0);

  Function f = &func;
  auto g = apply(arg, f);
  g();
  return 0;
}

----------------------------------------------------------------

Using built-in specs.
COLLECT_GCC=/software/thirdparty/gcc/4.9.1-0.el6_64/bin/g++
COLLECT_LTO_WRAPPER=/software/thirdparty/gcc/4.9.1-0.el6_64/libexec/gcc/x86_64-unknown-linux-gnu/4.9.1/lto-wrapper
Target: x86_64-unknown-linux-gnu
Configured with: ../configure --prefix=/software/thirdparty/gcc/4.9.1-0.el6_64
--with-system-zlib --enable-shared --enable-threads=posix --enable-laguages=all
--with-ppl --with-cloog --disable-multilib
Thread model: posix
gcc version 4.9.1 (GCC)

Reply via email to