This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug c++/61636] generic lambda: segfault / "cannot call member function without object"


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

Adam Butcher <abutcher at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Assignee|abutcher at gcc dot gnu.org        |unassigned at gcc dot gnu.org

--- Comment #22 from Adam Butcher <abutcher at gcc dot gnu.org> ---
Firstly, apologies for not unassigning myself from this; I hope it hasn't
stopped others from looking into it.  I had meant to unassign myself after my
last attempt to fix this in early 2015.  Since then I haven't had any spare
time to look into it.

The patch I submitted in 2015
(https://gcc.gnu.org/ml/gcc-patches/2015-04/msg00617.html) does indeed solve
this.  However, it captures 'this' in generic lambdas in some cases where it is
not required.

This is not ideal (see the follow up list discussion starting from Jason's
review https://gcc.gnu.org/ml/gcc-patches/2015-04/msg00934.html).

The current implementation, though non-optimal, may be preferable to waiting
for a better version as at least code can be written which is correct, minimal
and doesn't surprise users (i.e. no 'this->' workarounds required).

This bug could be closed in favor of a "'this' is captured in generic lambdas
when it is not necessary'" with proofs along the lines as I suggested in
https://gcc.gnu.org/ml/gcc-patches/2015-04/msg00959.html and
https://gcc.gnu.org/ml/gcc-patches/2015-04/msg00973.html.

I've just done some 'this' capture analysis using Clang (3.9.0), the current
stock ArchLinux GCC (6.2.1 20160830) and my own build of GCC (7.0.0 20161215)
including the patches above.

Clang stops short of a fully optimal solution.  In fact it is less optimal than
GCC even for monomorphic lambdas.  It seems to capture 'this' whenever it sees
a name within the lambda body that resolves to a member, whether or not that
reference requires 'this'.  It even captures 'this' when a reference is made to
static member of a _different_ class which is surprising.

The following show a handful of cases.  The comments inline indicate whether
'this' is captured (sizeof lambda == 8) or not captured (sizeof lambda == 1)
for Clang (C), GCC (G) and GCC with my 2015 patches (G').

The line tagged with the asterisk is the only case in this set where the patch
is non-optimal; "f (2.4)" unambiguously resolves to the static member "A::f",
so 'this' need not be captured.

Since, with the patch, GCC is correct and more optimal than Clang, I think it
would make sense to go with it and raise a separate ticket to address the other
issue.


struct A {
  void b ();
  void f (int);
  static void f (double);
};

struct O {
  void x (int);
  static void x (double);
};

namespace N {
  void y (double);
}

template <int> struct diag;

void A::b() {
  auto l0 = [&](auto z) { f (z); };    diag<sizeof l0> {}; // C:8 G:1 G':8
  auto l1 = [&](auto) { f (2.4); };    diag<sizeof l1> {}; // C:8 G:1 G':8 *
  auto l2 = [&](auto) { O::x (2.4); }; diag<sizeof l2> {}; // C:8 G:1 G':1
  auto l3 = [&](auto) { N::y (2.4); }; diag<sizeof l3> {}; // C:1 G:1 G':1
  auto l4 = [&](auto) { };             diag<sizeof l4> {}; // C:1 G:1 G':1
  auto l5 = [&](int z) { f (z); };     diag<sizeof l5> {}; // C:8 G:8 G':8
  auto l6 = [&](int) { f (2.4); };     diag<sizeof l6> {}; // C:8 G:1 G':1
  auto l7 = [&](int) { O::x (2.4); };  diag<sizeof l7> {}; // C:8 G:1 G':1
  auto l8 = [&](int) { N::y (2.4); };  diag<sizeof l8> {}; // C:1 G:1 G':1
  auto l9 = [&](int) { };              diag<sizeof l9> {}; // C:1 G:1 G':1
}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]