<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/56825>56825</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            nounwind declaration of _Unwind_Resume generates bad gcc_except_table
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            llvm:codegen
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          smeenai
      </td>
    </tr>
</table>

<pre>
    See https://godbolt.org/z/19c3ohsKs. The generated gcc_except_table is missing the call site table entry for the end of the function:

```
GCC_except_table0:
.Lexception0:
        .byte   255                             // @LPStart Encoding = omit
        .byte   255                             // @TType Encoding = omit
        .byte   1                               // Call site Encoding = uleb128
        .uleb128 .Lcst_end0-.Lcst_begin0
.Lcst_begin0:
        .uleb128 .Ltmp0-.Lfunc_begin0           // >> Call Site 1 <<
        .uleb128 .Ltmp1-.Ltmp0                  //   Call between .Ltmp0 and .Ltmp1
        .uleb128 .Ltmp2-.Lfunc_begin0           //     jumps to .Ltmp2
        .byte   0                               //   On action: cleanup
.Lcst_end0:
```

As a result, any exception thrown through this function will end up terminating, because we'll enter the cleanup, resume unwinding, and then the personality function will be unable to find any call site table entry corresponding to the cleanup PC.

Removing the `nounwind` attribute from the declaration of either `_ZN14has_destructorD1Ev` or `_Unwind_Resume` produces a correct gcc_except_table:

```
GCC_except_table0:
.Lexception0:
        .byte   255                             // @LPStart Encoding = omit
        .byte   255                             // @TType Encoding = omit
        .byte   1                               // Call site Encoding = uleb128
        .uleb128 .Lcst_end0-.Lcst_begin0
.Lcst_begin0:
        .uleb128 .Ltmp0-.Lfunc_begin0           // >> Call Site 1 <<
        .uleb128 .Ltmp1-.Ltmp0                  //   Call between .Ltmp0 and .Ltmp1
        .uleb128 .Ltmp2-.Lfunc_begin0           //     jumps to .Ltmp2
        .byte   0                               //   On action: cleanup
        .uleb128 .Ltmp1-.Lfunc_begin0           // >> Call Site 2 <<
        .uleb128 .Lfunc_end0-.Ltmp1             //   Call between .Ltmp1 and .Lfunc_end0
        .byte   0                               //     has no landing pad
        .byte   0                               //   On action: cleanup
.Lcst_end0:
```

This repros with any target using DWARF unwinding, not just Android AArch64.

I discovered this when building a combined libc++, libc++abi, and libunwind library with LTO, with libunwind providing the actual `_Unwind_Resume` definition; it resulted in various libc++ functions having bad gcc_except_tables, leading to exception handling issues. That's probably an unusual setup, but I'd still expect it to work.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJztV0uP2zYQ_jX2ZbCGJNvr9UEHx7spgi6aYNdFgV4MPsY2U4kU-LDj_voOKfm162xS5NBDI8gSRQ6H33wkv6G5kfvyGRE23jeuN5z1ivd0r43kpvIDY9f09Tf98qkYmo371Q1gsUFYo0bLPEpYC7HELwIbv_SMVwjKQa2cU3oNniwFqypwyiO0zai93cPK2NSKWoJZpeIqaOGV0RFEdt_LDs_brLvT5y_z-cVw2dF88NjWk4tTJXTXgO8JAUAxHsNbVxs-9EbZ46dnz6yHBy2MjMH0hvdgauV_1PFisW_we93mbzo9up0fSb7wGyrkeXH3wnVXC4NH4fySZiC7aYsc10pnBzbPal6xeXLh6yZ2j5PXWV8JevhAdwvyOYLMqWoe7ze85jet86_GDK1Djn6HqDsowGhBtf3fcl58C3K8Poe6ceBN1-X6BF3Bdx3sRw3ssL5BVMh0aM6pjvNwWvqXi759zhwwsOhC5XvFnCLdw3HF0w6yZte-wnpDb9qGhx0FO0VExa0WGvBoa6WZpzUSvXAULDiEHfaKSbIig3bjdhjJKA5aIwS9U1p2HSPRZKaTbYPWGc0q5fcvRuWxW9r4ROSKuifc10VBGEsjNSaNEe3PYMCn-eCcjCeszfagMUSUNi06KgLz3ioeyPvKmjpZSBQVI8GKuEhvUFGljf2Wf_6WjzbMLSU6b4Pwxt7nD9voxrQGvye_y6fEQaxvrJFBYJyNhFj4VyL4U8Pgp4b9nzTs6_H_O1aLb7Ga3HXzHUf4XlbzjtVj_x-kAoBEA7SBirVy1TD5n2eIRVR9iyRQjtTXb5LWkgKs0UNIJ7L7P2ZP7y-FXBtPy8R5mGlpjZIwm1mxuR1dyO0HkMoJs0WLsk0uu6j9PKgqRR-lsOZKU2uluOgV79I9P_tiXB3yBlW2EGLJMpL-hPZx8TFapPLJhKLZKnmQemIosOq6MEukBKNaBt-B8l2yJExKw5ZZZYI7A3TMVI7mMuUSzl6fZ12KAtkhJ51S7oZCqWItnXYDpoMxo8w8cREyp757Cpa4Di4idujbZEqJCT6QmQTnU17-0sQUQnDJ-87YvwZ9LPPb8bQo8tvpqC_LoZwOp6zvla-wPCS6lyntko7jAd1dDaofbFW-OPIT64EPaBrpo6q2h9cNBfOZANJnGycVxrd3xbi_KfMJk1M-QZFLRDGSciU5H04EZoIJvsJ-xThWruyNie8iOR3OSNuR0FFFb3zfV2WRFUU2GdJzPBoXg-mI3Y3EOJN3kQDBKdtgzVQ1iN3jH5K-LRMuHtaOGivlvDs1MvrnsdaIaUzyz4LfGFu6mpSAqX4KoUz4_wGrh8Yk">