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

    <tr>
        <th>Summary</th>
        <td>
            Catching custom exceptions thrown from shared libraries fails when using -flto 
        </td>
    </tr>

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

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

    <tr>
      <th>Reporter</th>
      <td>
          ilg-ul
      </td>
    </tr>
</table>

<pre>
    I have a failing test on the multi-platform [xPack LLVM/clang](https://github.com/xpack-dev-tools/clang-xpack/) when running on macOS.

It affects only macOS LTO builds, regular builds are fine. On GNU/Linux and MinGW-w64 the test passes.

The behaviour is the same on Apple clang version 14.0.0, xPack LLVM clang 15.0.7 and 16.0.6.

The code to run the test is:

```sh
mkdir ~/tmp/lto-throw-test
cd ~/tmp/lto-throw-test

cat <<'__EOF__' >throwcatch-lib.h
/*
 * Copyright (c) 2021 Martin Storsjo
 *
 * This file is part of llvm-mingw.
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#ifndef THROWCATCH_LIB_H
#define THROWCATCH_LIB_H

#include <exception>
#include <string>

class FirstException : public std::exception {
public:
 FirstException(const char *s) : str(s) {}

    virtual const char *what() const noexcept override {
        return str.c_str();
 }

private:
    std::string str;
};

class SecondException : public std::exception {
public:
    SecondException(const char *s) : str(s) {}

    virtual const char *what() const noexcept override {
 return str.c_str();
    }

private:
    std::string str;
};

void libFunc(int param);

#endif
__EOF__

cat <<'__EOF__' >throwcatch-lib.cpp
/*
 * Copyright (c) 2021 Martin Storsjo
 *
 * This file is part of llvm-mingw.
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#include "throwcatch-lib.h"
#include <stdio.h>

void libFunc(int param) {
    switch (param) {
    case 1:
 fprintf(stderr, "throwing FirstException\n");
 fflush(stderr);
        throw FirstException("first");
    case 2:
        fprintf(stderr, "throwing SecondException\n");
 fflush(stderr);
        throw SecondException("second");
    case 3:
        fprintf(stderr, "throwing std::exception\n");
 fflush(stderr);
        throw std::exception();
    default:
 fprintf(stderr, "not throwing\n");
        break;
 }
}
__EOF__

cat <<'__EOF__' >throwcatch-main.cpp
/*
 * Copyright (c) 2021 Martin Storsjo
 *
 * This file is part of llvm-mingw.
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#include "throwcatch-lib.h"
#include <string.h>
#include <stdio.h>

int main(int argc, char* argv[]) {
    int ret = 0;
    for (int i = 0; i <= 3; i++) {
        fprintf(stderr, "%d\n", i);
        int caught = 0;
        try {
            libFunc(i);
        } catch (FirstException &e) {
            fprintf(stderr, "caught FirstException\n");
            caught = 1;
            if (strcmp(e.what(), "first")) {
                fprintf(stderr, "unexpected what()\n");
                ret = 1;
            }
 } catch (SecondException &e) {
            fprintf(stderr, "caught SecondException\n");
            caught = 2;
            if (strcmp(e.what(), "second")) {
                fprintf(stderr, "unexpected what()\n");
                ret = 1;
            }
 } catch (std::exception &e) {
            fprintf(stderr, "caught std::exception\n");
            caught = 3;
        } catch (...) {
            fprintf(stderr, "caught something else\n");
 caught = -1;
        }
        if (caught != i) {
 fprintf(stderr, "caught unexpected exception!\n");
            ret = 1;
        }
    }
    if (ret)
        fprintf(stderr, "\ngot errors\n");
    else
        fprintf(stderr, "\nall ok\n");
 return ret;
}
__EOF__

echo "First test without -flto:"

clang++ throwcatch-lib.cpp -shared -fpic -o libthrowcatch-lib.dylib -std=c++11
clang++ throwcatch-main.cpp -o throwcatch-main -L. -lthrowcatch-lib -std=c++11

echo

./throwcatch-main

echo "Now test the same with -flto:"

clang++ throwcatch-lib.cpp -shared -fpic -o liblto-throwcatch-lib.dylib -std=c++11 -flto
clang++ throwcatch-main.cpp -o lto-throwcatch-main -L. -llto-throwcatch-lib -std=c++11 -flto

./lto-throwcatch-main
```

As shown in the copyright notices, the actual tests are from the [llvm-mingw](https://github.com/mstorsjo/llvm-mingw) project, by @mstorsjo.

The output I get on a macOS 12.6.7 with CLT installed is:

```console
First test without -flto:

0
not throwing
1
throwing FirstException
caught FirstException
2
throwing SecondException
caught SecondException
3
throwing std::exception
caught std::exception

all ok

Now test the same with -flto:
0
not throwing
1
throwing FirstException
caught std::exception
caught unexpected exception!
2
throwing SecondException
caught std::exception
caught unexpected exception!
3
throwing std::exception
caught std::exception

got errors
```
 
As it can be seen, `FirstException` and `FirstException` are caught as `std::exception`. Without `-flto`, they are caught as expected.

Is this a bug or am I missing something when using LTO?




</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzsWl9vqzoS_zT0ZRRETJO2D32gCTRIaegGeqr7VDlggu8hNrJNevqyn31lQxLyp2lvz5F2tSqKEsCemZ9_tmfGdrCUdMkIubUGd9ZgfIFrVXBxS8tlry4vFjx7uw2hwGsCGHJMS8qWoIhUwBmogsCqLhXtVSVWORcrsAZ3vx5x-hOm0x8PFgrSErOlNRhb6LpQqpKW61kosFCwpKqoF3bKVxYKflU4_dnLyLqnOC_lRq5n3pv6N_BaEAaiZkwj4AxWOI1i23LGluM136ECnOckVRI4K9-aGjBNIljUtMykhUYgyLIusWjfABYEcsqIDRGD-9mThYIpZfUvwCyDB8run3uvw0vTUNPoCktJ5J7VpCCwIAVeU14LoNJUlnhFNEivqkoCpjGwJkJSzqB_aTu2o8HsmGqr9Ae2Y18Z4_2h7djDI0spzwgoronYoaKG1k5Na-g0H1k0L1Y_Myrg3xYK1KqyUFAq3lOF4K89raCpk2YfVGirYQWWO9IfdPXy4kfBy4uFrsByfSOQYpUWvZIu7Na26b9WGCzkwYhXb4IuCwUWuk513yIH9eEBC0UZxIoL-Tff1e9IJgWVkNOSaJ4rLBTwHMpyveqtKFu-2ieFHolYUWmoVxxqSTT1Ka_e9O-KZzQ3d5hlFgq4gIxKJeiiVgSUtid5rl7NQOECMHvrqK5qUXFJ4JWqArgwv7xWkBODsCCCLN5gKTBTJNNGKsHXNCMZqAIr04F4wdekozLdksO4oikxg8HgqHbt2BRVFcECKANcllqSbsfmIXETH-IoSJ69uQ9hDI_z6Ec49sdgIeTFEMYWQuDNxqai95RMojmMw3g09cKHGLzpFJ69-dybJaEfd9Q-h8kE5v69Nx9DEkEyCeOOmdlo-jQOZ_dGPnx4nIb-uKMHoqCj6sGfjybeLPHuwmmY_GXABGEy8-PYhnAGswj8H_4sgXii1XVw3vkwDb27qQ9BNO9o9GZ_Qfzoj0Jvqqkfh3N_lOi7cLa7j-Ywimax_68nf5aE3hTG3oN3r8HNjYL2sdvmiZfEkf_Dn8Pcj5-miW5hMI8eYBrFulHwFPvGoJd4Ws3jPArCJNavnid-MvHnuj3erAt1lITRTMuOolky9xpsM_9-Gt77s5Gv1URGMonmSRg9xa2IrubNw1hjiJ6SfUojY2gUzWZ-o990l2buKTYqH_15EM0fPGMh2O--7jhCwZ5zQS7NWUZySCbz6HnkJaPJyzS8e5lsyzOinep75VstLC3rjGhvQn6lpFKUM8v1T5XrGcmWu8LGE5VYSgiokMrfyIPl6mm5KGkKUmXaL7oe2ZVe3TWyTZWt2zzQov0SZ1JBWmChKZDaS2nVUgkLXTePV3fW1bgLCABgTYWqsZ6NXfnXAisLXWuxpoDxBhTwNRGC6lZuoEF7CaJqwbRFO31p7FroxnI31Q6MV4KusSK7JgHsGGj4M-g38lp8e9_hMyYpZ9lvEwpwqOm_S-pHbAL8eULXnGZQ0kVQs9RC15TpBELgVdfwdrQTltG8edpE1S9F3bSqvuPud9z9jrv_j3F3ExEROsq1ETodODPK7eIgcp5xTPtxSL5SlRbaX5wuT7Ek0N-5yLwSlKlce3OVESE0Txuw2l8ehNnBiGncXT-c52Uti46CfR-tL6PtOGJbCOX63aHGDUy058n19RHawwD2O3CPg6GFkDQv3wPs_mPAxwH6tzCfUHccNTOS47pUH44BxhVsgJ5C1V4LQfDPU0nO5ubLwXGFKfuOjt_R8Ts6fkfHvWVlNzx-InjqaKl9SRs4sVimZu4WWOj2YbFcN3upR9FSVxdE-6oxOHueT0_iVh_dFpvbkX5yzZOF7szn5nit-I7PtdAg2_rakdZw7HC1zRTXxvEd4TKxQLwdG9RXJ4E4pdi6GoPpAt2yw1U6GpKTDTnTmBbkxylE5-o0rH-yAs3B2BHpqrLQNbF3i8rWbDeneA_xGdQ1I78qkiqSQUf1edTt6v8M7G003Gf5aO3-dZo_kfuc5hl9kee9XOh_nehTOyFf5_pzadtput3z88627a-C4iuiCp1VklKSU4A6KHrH7O2Y2xsCGyHU13J0H9x5RJ0e7iSk_Q-4er9_9xDuPTRQBVFa6acc7WDEllwBEYIL-Q4iw-Nntencif88pandydLoultP7yXHJC24Vmr8ZnNetEkIe3mpuDmRQwf7gGzZBBs43lyCniywIBn08oqm0OM6DhxUy95KuoCeGdfjtFHV75_VvsnOtcKD19Cb2tAr9228o33X5u6zbaHgQOkpimb8tSFoe4RnUug_R9P2VO0jqlqbnyXsQG-HtGOLZ23t6Dqhsq2yOVvsSngSZMFfmc76lTmm3F8vmLNXs7BIzUauZrk9fRV8ZUqswd1uzfThifFKtgsyFHSk0I1ey_xNUqXtLd7AunQ2NY-OUnmtqlpBCEtiTrNxe2DcR_bQvmq6fjRNgDKpcFmS7Mw5a8qZ5GU7u8_NtI5wS-Deuti8aYfye5sm7ZL3VDJkitCB-GEk78qfLHMPFJwIT10d7xU3360f67z5aJb9MXI-wP1eOPnHJP6OnT_KdScCnZqqsJ2rVKf8DBYEJCHMRJ2hc8Dk0DGL_NMFgmyiP5a6yglcQ8eG53b4W0On6d6h0zqCtwMdG4r2_9Ahmz0GDIt6CVwAXkEIZrtBU7VNUMxfQ2rzcppElru_MOx8X2S3bnbj3uALctsf3vRd1B8Mri-K2zx3sJPhQba4SvHgZkCQ279O3UvHzfObhTu4oLfIQa5z7Qz7fRe513aGsHOT9l2U3lz1U4SsS4esMC1t7Y5sLpYXVMqa3A4vL6_6FyVekFKa_9ggxMgrmEIT6scX4ta4sEW9lNalU1Kp5E6LoqoktyPthHX70loqvtoNJNlMD9b40TbklHQhsKBEmn_syC4_phvgohbl7Rnvqq1vPOvWoQYGs7RQYNr0nwAAAP__ppx49g">