jeudi 26 avril 2018

`std::terminate` invocation in a `noexcept` function with limited visibility - gcc vs clang codegen

Consider the following code snippet:

void f();

void a()          { f(); }
void b() noexcept { f(); }

In the scenario above, the body of f is not visible to the compiler in the current translation unit. Therefore, since b is marked noexcept, additional code must be generated on the caller side to make sure that the exception is caught and std::terminate is invoked.

That's what clang++ -Ofast -std=c++2a does (trunk version):

a(): # @a()
  jmp f() # TAILCALL
b(): # @b()
  push rax
  call f()
  pop rax
  ret
  mov rdi, rax
  call __clang_call_terminate
__clang_call_terminate: # @__clang_call_terminate
  push rax
  call __cxa_begin_catch
  call std::terminate()

However, g++ -Ofast -std=c++2a does not (trunk version):

a():
  jmp f()
b():
  jmp f()

live example on godbolt.org


How does g++ get away with this? Shouldn't code be generated on the caller side as the body of f is not visible?

...or is this just a weird Compiler Explorer quirk?

Aucun commentaire:

Enregistrer un commentaire