Итак, берём лютый говнокод
int main()
{
auto f = [](void* ptr) { goto *ptr; };
f(&&label);
label:
return 0;
}
*** stack smashing detected ***: ./a.out terminated
Aborted (core dumped)
Но стоит только включить уровень -O2... (компиляция на вышеупомянутом сайте, gcc HEAD 7.0.0 20161113 (experimental))
prog.cc: In function 'main()::<lambda(void*)>':
prog.cc:3:23: internal compiler error: Segmentation fault
auto f = [](void* ptr) { goto *ptr; };
^
0xaf60df crash_signal
/home/heads/gcc/gcc-source/gcc/toplev.c:338
0xb2c48d cleanup_control_flow_bb
/home/heads/gcc/gcc-source/gcc/tree-cfgcleanup.c:250
0xb2c741 cleanup_tree_cfg_1
/home/heads/gcc/gcc-source/gcc/tree-cfgcleanup.c:702
0xb2c741 cleanup_tree_cfg_noloop
/home/heads/gcc/gcc-source/gcc/tree-cfgcleanup.c:766
0xb2c741 cleanup_tree_cfg()
/home/heads/gcc/gcc-source/gcc/tree-cfgcleanup.c:817
0xa403c4 execute_function_todo
/home/heads/gcc/gcc-source/gcc/passes.c:1918
0xa4137b execute_todo
/home/heads/gcc/gcc-source/gcc/passes.c:2015
Please submit a full bug report,
with preprocessed source if appropriate.
Please include the complete backtrace with any bug report.
See <http://gcc.gnu.org/bugs.html> for instructions.
Самая младшая падающая версия — gcc 4.6.4 (на вышеупомянутом сайте). Версии проверял не все, только несколько верхних и нижних плюс пару промежуточных, они крашатся. Думаю, крашатся все промежуточные.
Похоже, разработчики g++ не были готовы к тому, что их расширение «Labels as Values» будут скрещивать с лямбдами.
Кстати, clang++ отвергает код с такой формулировкой:
prog.cc:3:27: error: indirect goto in function with no address-of-label expressions
auto f = [](void* ptr) { goto *ptr; };
^
Воспользуемся воркэраундом, приведённом в багрепорте и изменим лямбду:
auto f = [](void* ptr) { goto *ptr; crap: void *pcrap = &&crap; };
При этом g++ начинает лучше оптимизировать код: в первоначальной версии кода, на уровне -O1 остаётся вызов лямбды, а в версии с dummy-меткой в лямбде main компилируется просто как обнуление eax и возврат. clang++ с -O1 оптимизирует main до такого же состояния. Правда, я подозреваю, это не результаты инлайнинга, а результаты выкидывания кода с UB.
Такие дела.
Что касается багрепорта — я его организую как только мне выдадут доступ к gcc-шной багзилле.