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

    <tr>
        <th>Summary</th>
        <td>
            [libc++abi] Incorrect catches (macOS) (or segv CE) for some thrown pointer cases
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            new issue
      </td>
    </tr>

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

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

<pre>
    We should be able to throw and catch null pointers to objects.

(this is easier to see on macOS, with currently-installed versions of libc++abi, but we also fail on compiler explorer)

e.g. 

https://godbolt.org/z/fjdhvev93  (non-virtual bases only)

https://godbolt.org/z/qj8nah55j (virtual bases)

NOTE1: libstdc++ / libsupc++ handle this fine on both macOS and Linux.
NOTE2: This is repeatable with GCC / libstdc++ / libc++abi (but that is only possible with WIP patches to allow the use of c++abi there).

Analysis
---------

The failing cases are when we throw a null pointer-to-object.

The underlying reason for the fail is that the code in private_typeinfo.cpp:
(__base_class_type_info::has_unambiguous_public_base() and the other class impls. + process_found_base_class()) inspects the thrown object layout to determine whether we have seen distinct copies of base classes (and it uses the thrown object to do that).

In the case of a thrown pointer, we pass the pointer-to-object to the methods mentioned above.

However, if those methods see that the pointer is null they (mostly reasonably) refuse to use it to figure out the layout; this means that process_found_base_class() then makes the wrong call on whether base classes are distinct.

Possible ways forward
----------------------

I spent some time looking at this (a) to analyse and (b) to see if I could come up with a patch.

1) In the case where we have non-virtual base classes, we can actually make this work by pretending we have a dummy object based at 0.  Since the __base_class_type_info only contains actual offset of bases, we can compute the layout without having a real object (since we never actually access the object vtables).

2) In the case of virtual bases the situation  is much more difficult, since the current code actually inspects the vtables of the thrown object - e.g. __base_class_type_info contains negative offsets to vtable entries, and those are dereferenced to find tha actual offset to the virtual base.  Clearly, we cannot do that without an object.

So .. I have a WIP patch that does (1) [which I will put on phab as a draft after some more testing]
 ... but currently no real plan/idea on how to deal with (2)


</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJyEVk-P4j4S_TThUiKiTdPAgUP_-bHb0mpnpBlpjshxKtg9jitrO2TYT78qO6GBmd3l0DSJXX_ee_VsGYI5OsRdsXopVm8z2UdNfmekcWFWUX3e_UAImnpbQ4UgK4sQCaL2NIB0NSgZlQbXWwsdGRfRB15A1QeqGMpi8VYsnse_YhO1CWACoAwGPS8MiEAOWqm-fCvEKwwmalC99-iiPc-NC1FaizWc0AdDLgA1YE2lCvFSiBdZGd5V9REGBGkDQSON5ZCK2s5Y9IC_OksefSG21-VgeSzh-oGOsQvF8rkQ-0Lsj1RXZGNJ_liI_b8LsW8-an3C03YJUIiNIzc_GR97aaGSAQOQs-e7HP8v5L8-Nk7q1eqDI95Euwv0zy_f_3ools_ceoj12D0UYp-e9N30REtXM0cMdGNcAreiqDPCibJ_GNf_Kj_jCo77fWTGY4cyJp4TFX97fb1k-S3vJwlcP5MQtYwchrGAjkIwl0g_3r9Cx2rBpBBpLQ0QNUIfkEm9ChY1eizE9kY-z07aczAh_5pPn-sl3zUm-o07gkqcSI8waHSsjlG0N2KdR5pnrZb3gXpXo7dnjuVRBnLQkE8FJ4WZkJvlB4pqBOOg8-YkIx7iuUPjGipV1zH7k_wPB-b2oKwMIS068CpesXzWMhx6J9vKHHvqw6HrK2tU2lCITSG2iTvORgwPpCBg2s6GEpiTzpPCEA4N9a6-SpR3cwDjQsdTmaIkNNw4qGDlmZg-ghoj-paVM2hMmQYELU_Io-qgNiEapyIo6gymaeRUuRwMrAOu00Sm9U-ZOAUl6O4JfncZTJn1IKeNI1XJHRA6bpvX_cZgNiaEFqOmOkCLLhpyWIOs6IQ3uf5OA55yTNNA1BQ-97ElXagdszDdSTdR45mbbClEex6VIas0-eCxYTFHSpo2qaLGHHuPkNDVOAJdLF_yiLYo3Sik_80fb2ab_DmCOnhKIrfJ6yaqbqhg7U903TT_9TKX8hxY1YP09d1Y3XxuWILQoYsQqEWIpkWwRD95ShJiJksgVUwg08xiki47xPiYETYNvINKB4viUH2XbUJmk7gp-IH3XctjYIO4CPPeiicERsUo6UAqfmvPCcFc5kD-J1Rn6DxGdDV3MAWUUPdte54kyzFrbm9RAnwzTmGq5M_TnK1PkYt8ho6JgZomYJym5boyPqb6iFfiSDjwt5anhCurzE7FFGITUgkDgmMNf_YmFQsoe0RefEpOHu4nTdzjSQ3cnmX8JpjYS54gYPW3vdLQUtJU0xjV28hdhAsc46GdzfBS043njOVwut-NYQ7pRP4vqF4AdXiU0ZxwhDSdJTkuoIveZHCzV_JUpylAjw16dArrPJPptbxjZ_SPayRKgFeL0vN8T5Q5ipOFXaiSUxs3OH8jKEt4n0R1OQHz3pqyXyZ1F6uXQRul4R0Gw-dTH3mwOy0rkIEV6WUTQTZsRmn2EhcReb6PxeotZ4SyLNNt6HKFAkdZP52VrhB7U6PkyJpPX7Z7afPgFWIj7m4ds3q3rLfLrZzh7uFpKzZP2_ViPdO7NT6s5VOzWtSP9VO9WK9XK1yoVbV-eBQL9VTPzE4sxHKxEY-L7XK1WJebSq1wvW7k47ZS63VVPC6wlcaW1p5avhHNTAg97p4et6vlzMoKbUiXUiEcDpBeFkLwHdXveM-86o-heFxYE2L4jBJNtOk2e3tHXL3Bu1PkPStNjbcQtvF879zy_-Qh4PEEr3_xAz7ss8fdnEL5XjHrvd3dXe5M1H1VKmoLsedyxq9554mFwdBzE6EQ-9TkfwIAAP__MWfYhw">