https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109267
Bug ID: 109267 Summary: -Og generates empty functions with .cfi_startproc/.cfi_endproc that conflict with other functions Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: i at maskray dot me Target Milestone: --- cat > lib.cpp <<'eof' #include "lib.h" #include <stdexcept> void test(const T_value& entry_value) { boost::apply_visitor([](const auto& value) { test(value); }, entry_value); } void test(const Obj_1& ) { throw std::runtime_error("Obj_1"); } void test(const Obj_2& ) { throw std::runtime_error("Obj_2"); } eof cat > lib.h <<'eof' #pragma once #include <boost/variant.hpp> struct Obj_1 { int i; }; struct Obj_2 { int i; }; using T_value = boost::make_recursive_variant< Obj_1, Obj_2>::type; void test(const T_value&); void test(const Obj_2&); void test(const Obj_1&); eof cat > main.cpp <<'eof' #include "lib.h" #include <stdexcept> int main() { try { test(Obj_2{2}); } catch (const std::runtime_error& e) { } try { test(Obj_1{1}); } catch (const std::runtime_error& e) { } } eof g++ -isystem /usr/include/boost -Og -g -DNDEBUG -S lib.cpp main.cpp g++ -isystem /usr/include/boost -Og -g -DNDEBUG -fuse-ld=lld lib.cpp main.cpp return lib.s has unusual empty functions with .cfi_startproc/.cfi_endproc . I think this behavior is incorrect since CFI FDE associated to the empty functions may conflict with FDE of another function. When linking with GNU ld, GNU ld drops FDE associated to the empty functions, and therefore the output executable will be correct. However, I think linkers are not obliged to behave like GNU ld. ld.lld doesn't discard FDE associated to the empty functions, and the output executable will call std::terminate. ``` % ./a.out terminate called after throwing an instance of 'std::runtime_error' what(): Obj_1 [1] 2826366 IOT instruction ./a.out ``` -O1/-O2/-O3 discard such empty functions to avoid the problem. In -O0 codegen, the function becomes non-empty, avoiding the problem as well. ``` % g++ -isystem /usr/include/boost -Og -g -DNDEBUG -S lib.cpp -o - | grep 11result_typeEiRSD_T0_PNS1_22apply_visitor_unrolledET1_l .type _ZN5boost6detail7variant22visitation_impl_invokeINS1_14invoke_visitorINS1_15result_wrapper1IZ4testRKNS_7variantINS1_14recursive_flagI5Obj_1EEJ5Obj_2EEEEUlRKT_E_SC_EELb0EEEPKvNSA_18has_fallback_type_EEENSD_11result_typeEiRSD_T0_PNS1_22apply_visitor_unrolledET1_l, @function _ZN5boost6detail7variant22visitation_impl_invokeINS1_14invoke_visitorINS1_15result_wrapper1IZ4testRKNS_7variantINS1_14recursive_flagI5Obj_1EEJ5Obj_2EEEEUlRKT_E_SC_EELb0EEEPKvNSA_18has_fallback_type_EEENSD_11result_typeEiRSD_T0_PNS1_22apply_visitor_unrolledET1_l: .size _ZN5boost6detail7variant22visitation_impl_invokeINS1_14invoke_visitorINS1_15result_wrapper1IZ4testRKNS_7variantINS1_14recursive_flagI5Obj_1EEJ5Obj_2EEEEUlRKT_E_SC_EELb0EEEPKvNSA_18has_fallback_type_EEENSD_11result_typeEiRSD_T0_PNS1_22apply_visitor_unrolledET1_l, .-_ZN5boost6detail7variant22visitation_impl_invokeINS1_14invoke_visitorINS1_15result_wrapper1IZ4testRKNS_7variantINS1_14recursive_flagI5Obj_1EEJ5Obj_2EEEEUlRKT_E_SC_EELb0EEEPKvNSA_18has_fallback_type_EEENSD_11result_typeEiRSD_T0_PNS1_22apply_visitor_unrolledET1_l % g++ -isystem /usr/include/boost -O1 -g -DNDEBUG -S lib.cpp -o - | grep 11result_typeEiRSD_T0_PNS1_22apply_visitor_unrolledET1_l % g++ -isystem /usr/include/boost -O2 -g -DNDEBUG -S lib.cpp -o - | grep 11result_typeEiRSD_T0_PNS1_22apply_visitor_unrolledET1_l % g++ -isystem /usr/include/boost -O3 -g -DNDEBUG -S lib.cpp -o - | grep 11result_typeEiRSD_T0_PNS1_22apply_visitor_unrolledET1_l ``` Link: https://github.com/llvm/llvm-project/issues/61434