This patch fixes three issues with how Clang emits code to catch exceptions by reference:
- We would sometimes bind the reference directly to the exception object when a temporary is required (when a pointer-to-member is converted by a qualification conversion but not adjusted).
- We would sometimes bind the reference to a temporary when a direct binding is required (when catching a pointer-to-class-object where no derived-to-base or qualification conversion is required).
- We would incorrectly allow a non-const (or volatile) reference to catch an exception of a different type that can be converted to the right type.
A single strategy is used to fix all three issues: where necessary, we extract the type_info of the exception object from the __cxa_exception header, and compare it directly against the reference's pointee type_info. For cases #1 and #2, this tells us whether to bind to a temporary object or to the exception object; for case #3, if the types don't match and the reference can't bind to a temporary, we rethrow the exception through the remaining catch clauses of the try statement.
This patch is insufficiently tested (no changes to the test suite, and no testing has been done whatsoever for the ARM64 non-unique type_info case), but I'm posting it now to gauge whether this is a direction we want to pursue for DR388 (as opposed to continuing to get this wrong until the Itanium C++ ABI has a chance to take an ABI break to properly handle catch-by-reference).
[Despite the different approach to determining catchability, the MS ABI appears to have exactly the same bugs (it too does not distinguish between catch by value and catch by reference), and I would assume the same approach would also work there, assuming the actual type of the exception object can be discerned, but I've not looked at all at implementing this in that ABI.]
Based on our conversation, this fix feels a bit heroic. I think it would be better to find a way to put the const-ness in the LSDA and let new versions of the EH runtime deal with this.