Falha de segmentação no gcc causada pelo wrapper lambda durante a chamada de função do modelo variada

Passei algumas horas hojetentando entender por queesse código segfaults emg++6.2 eg++7.0, trabalhando alegremente como planejadoclang++3.9 (e4.0).

Reduzi o problema para umSnippet de código independente de 85 linhas, qualnão segfault na execução normal, massempre relata um erro no UBSAN.

O problemaé reproduzível na caixa de varinha, compilando comg++7, permitindo otimizações e aprovação-fsanitize=undefined como uma bandeira extra.

É isso que a UBSAN relata:

prog.cc: In function 'int main()':
prog.cc:61:49: warning: 'ns#0' is used uninitialized in this function [-Wuninitialized]
         ([&] { ([&] { n.execute(ns...); })(); })();
         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~
prog.cc:28:10: note: 'ns#0' was declared here
     auto execute(TNode& n, TNodes&... ns)
          ^~~~~~~
prog.cc:30:9: runtime error: member call on null pointer of type 'struct node_then'

g++ afirma quens#0 é não inicializado dentro da "linguagem lambda"(que simula ofor_tuple do snippet original). Agora, algumas coisas muito interessantes ocorrem:

Se eu remover o "jargão lambda", transformandolinha 61 para dentro

 n.execute(ns...);

então o UBSAN para de reclamar.

E seEu mudo a lista de captura de[&] para[&n, &ns...], O UBSAN também para de reclamar:

 ([&](auto) { ([&n, &ns...] { n.execute(ns...); })(); })(0);

...espere o que? Como isso é diferente de[&]?

Aplicando as descobertas acima ao snippet de código originalcorrige os segfaults.

Isso é umg++ erro? Ou existe algum comportamento indefinido no meu código?

questionAnswers(1)

yourAnswerToTheQuestion