<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Sun, May 11, 2014 at 8:19 AM, Stephan Tolksdorf <span dir="ltr"><<a href="mailto:st@quanttec.com" target="_blank">st@quanttec.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi,<br>
<br>
When clang/LLVM can't prove that a noexcept function only contains non-throwing code, it seems to insert an explicit exception handler that calls std::terminate. Why doesn't clang leave it to the eh personality function to call std::terminate when an exception is thrown inside a noexcept function, as GCC does?<br>
</blockquote><div><br></div><div>As far as I can see, this is impossible to represent in LLVM IR. (If there is a way, I'm sure we'd be happy to make clang emit that IR.)</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

For example, GCC generates more efficient code for this test case:<br>
<br>
  using FP = void(*)();<br>
<br>
  inline void test(FP fp) noexcept {<br>
    fp();<br>
  }<br>
<br>
  void test2(FP fp) {<br>
    test(fp);<br>
    test(fp);<br>
  }<br>
<br>
The code generated by GCC (ToT, -O3, Linux x64) is:<br>
<br>
.LHOTB0:<br>
        .p2align 4,,15<br>
        .globl  _Z5test2PFvvE<br>
        .type   _Z5test2PFvvE, @function<br>
_Z5test2PFvvE:<br>
.LFB1:<br>
        .cfi_startproc<br>
        .cfi_personality 0x3,__gxx_personality_v0<br>
        .cfi_lsda 0x3,.LLSDA1<br>
        pushq   %rbx<br>
        .cfi_def_cfa_offset 16<br>
        .cfi_offset 3, -16<br>
        movq    %rdi, %rbx<br>
        call    *%rdi<br>
        movq    %rbx, %rax<br>
        popq    %rbx<br>
        .cfi_def_cfa_offset 8<br>
        jmp     *%rax<br>
        .cfi_endproc<br>
.LFE1:<br>
        .globl  __gxx_personality_v0<br>
        .section        .gcc_except_table,"a",@<u></u>progbits<br>
.LLSDA1:<br>
        .byte   0xff<br>
        .byte   0xff<br>
        .byte   0x1<br>
        .uleb128 .LLSDACSE1-.LLSDACSB1<br>
.LLSDACSB1:<br>
.LLSDACSE1:<br>
        .text<br>
        .size   _Z5test2PFvvE, .-_Z5test2PFvvE<br>
        .section        .text.unlikely<br>
<br>
<br>
The code generated by clang (ToT, -O3, Linux x64) is:<br>
<br>
.globl  _Z5test2PFvvE<br>
        .align  16, 0x90<br>
        .type   _Z5test2PFvvE,@function<br>
_Z5test2PFvvE:                          # @_Z5test2PFvvE<br>
        .cfi_startproc<br>
        .cfi_personality 3, __gxx_personality_v0<br>
.Leh_func_begin0:<br>
        .cfi_lsda 3, .Lexception0<br>
# BB#0:                                 # %entry<br>
        pushq   %rbx<br>
.Ltmp6:<br>
        .cfi_def_cfa_offset 16<br>
.Ltmp7:<br>
        .cfi_offset %rbx, -16<br>
        movq    %rdi, %rbx<br>
.Ltmp0:<br>
        callq   *%rbx<br>
.Ltmp1:<br>
# BB#1:                                 # %_Z4testPFvvE.exit<br>
.Ltmp3:<br>
        callq   *%rbx<br>
.Ltmp4:<br>
# BB#2:                                 # %_Z4testPFvvE.exit3<br>
        popq    %rbx<br>
        retq<br>
.LBB0_3:                                # %terminate.lpad.i<br>
.Ltmp2:<br>
        movq    %rax, %rdi<br>
        callq   __clang_call_terminate<br>
.LBB0_4:                                # %terminate.lpad.i2<br>
.Ltmp5:<br>
        movq    %rax, %rdi<br>
        callq   __clang_call_terminate<br>
.Ltmp8:<br>
        .size   _Z5test2PFvvE, .Ltmp8-_Z5test2PFvvE<br>
        .cfi_endproc<br>
.Leh_func_end0:<br>
        .section        .gcc_except_table,"a",@<u></u>progbits<br>
        .align  4<br>
GCC_except_table0:<br>
.Lexception0:<br>
        .byte   255                     # @LPStart Encoding = omit<br>
        .byte   3                       # @TType Encoding = udata4<br>
        .asciz  "\242\200\200"          # @TType base offset<br>
        .byte   3                       # Call site Encoding = udata4<br>
        .byte   26                      # Call site table length<br>
.Lset0 = .Ltmp0-.Leh_func_begin0        # >> Call Site 1 <<<br>
        .long   .Lset0<br>
.Lset1 = .Ltmp1-.Ltmp0                  #   Call between .Ltmp0 and .Ltmp1<br>
        .long   .Lset1<br>
.Lset2 = .Ltmp2-.Leh_func_begin0        #     jumps to .Ltmp2<br>
        .long   .Lset2<br>
        .byte   1                       #   On action: 1<br>
.Lset3 = .Ltmp3-.Leh_func_begin0        # >> Call Site 2 <<<br>
        .long   .Lset3<br>
.Lset4 = .Ltmp4-.Ltmp3                  #   Call between .Ltmp3 and .Ltmp4<br>
        .long   .Lset4<br>
.Lset5 = .Ltmp5-.Leh_func_begin0        #     jumps to .Ltmp5<br>
        .long   .Lset5<br>
        .byte   1                       #   On action: 1<br>
        .byte   1                       # >> Action Record 1 <<<br>
                                        #   Catch TypeInfo 1<br>
        .byte   0                       #   No further actions<br>
                                        # >> Catch TypeInfos <<<br>
        .long   0                       # TypeInfo 1<br>
        .align  4<br>
<br>
        .section .text.__clang_call_terminate,"<u></u>axG",@progbits,__clang_call_<u></u>terminate,comdat<br>
        .hidden __clang_call_terminate<br>
        .weak   __clang_call_terminate<br>
        .align  16, 0x90<br>
        .type   __clang_call_terminate,@<u></u>function<br>
__clang_call_terminate:                 # @__clang_call_terminate<br>
# BB#0:<br>
        pushq   %rax<br>
        callq   __cxa_begin_catch<br>
        callq   _ZSt9terminatev<br>
.Ltmp9:<br>
        .size   __clang_call_terminate, .Ltmp9-__clang_call_terminate<br>
<br>
- Stephan<br>
______________________________<u></u>_________________<br>
cfe-dev mailing list<br>
<a href="mailto:cfe-dev@cs.uiuc.edu" target="_blank">cfe-dev@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev" target="_blank">http://lists.cs.uiuc.edu/<u></u>mailman/listinfo/cfe-dev</a><br>
</blockquote></div><br></div></div>