Search code examples
c++macosexceptionclangc++20

C++ Exception not caught on clang 17.0.3


This is a simplified version of a bug that I ran into today.

#include <iostream>
#include <vector>
#include <stdexcept>

void run() {
    std::vector<int> v;
    throw std::runtime_error("error");
}

int main() {
    try {
        run();
    } catch (const std::exception &e) {
        std::cerr << e.what() << std::endl;
        return 1;
    }

    return 0;
}

I compiled and ran this code with Homebrew clang version 17.0.3 on an M1 Mac:

clang++ -std=c++20 -o main main.cpp

The exception is not caught and the program exits with:

Process finished with exit code 133 (interrupted by signal 5: SIGTRAP)

If I remove std::vector<int> v; from the run function or compile it on Linux, then it works.

Edit: So, I was originally compiling through CLion using cmake which also added -L/opt/homebrew/opt/llvm/lib.

I tested it compiling manually, results:

# works
clang++ -std=c++20 -o main main.cpp

# crashes with c++11, c++17 and c++20
clang++ -std=c++20 -O0 -o main -L/opt/homebrew/opt/llvm/lib main.cpp

# works
clang++ -std=c++20 -O1 -o main -L/opt/homebrew/opt/llvm/lib main.cpp

My guess is that -O1 simply stripped away creating the vector, because adding more code to make sure it's kept causes a trap.

Creating an empty class inside run(), that has a destructor that prints something also causes this same problem.


Solution

  • It was a misconfiguration error.

    Excerpt from brew info llvm.

    ==> Caveats
    To use the bundled libc++ please add the following LDFLAGS:
      LDFLAGS="-L/opt/homebrew/opt/llvm/lib/c++ -Wl,-rpath,/opt/homebrew/opt/llvm/lib/c++"
    
    llvm is keg-only, which means it was not symlinked into /opt/homebrew,
    because macOS already provides this software and installing another version in
    parallel can cause all kinds of trouble.
    
    If you need to have llvm first in your PATH, run:
      echo 'export PATH="/opt/homebrew/opt/llvm/bin:$PATH"' >> ~/.zshrc
    
    For compilers to find llvm you may need to set:
      export LDFLAGS="-L/opt/homebrew/opt/llvm/lib"
      export CPPFLAGS="-I/opt/homebrew/opt/llvm/include"
    

    Using -L/opt/homebrew/opt/llvm/lib/c++ the code runs as expected.