Segmentation Fault in LLVM Module Generation

Hello everyone!
I’ve been working on a code to generate LLVM IR module from C, CXX and CC files in code. I’ve used Clang’s Compiler Instance class and EmitLLVMAction class for the job. However, the code doesn’t work for files that include headers. I had to explicitly mention the include paths, which I thought should’ve been done by the Clang API. Is there a better way to approach this? Other than this, the main issue is that it does generate the module but throws a segmentation fault. I tried using valgrind but couldn’t understand.


int main(int argc, char* argv[]) {

    // Prepare compilation arguments
    vector<const char *> arg;

    // Explicitly Add Include Paths

    llvm::ArrayRef<const char *> args(arg);


    // Prepare DiagnosticEngine 
    DiagnosticOptions DiagOpts;
    TextDiagnosticPrinter *textDiagPrinter = new clang::TextDiagnosticPrinter(errs(), &DiagOpts);
    IntrusiveRefCntPtr<clang::DiagnosticIDs> pDiagIDs;
    DiagnosticsEngine *pDiagnosticsEngine = new DiagnosticsEngine(pDiagIDs, &DiagOpts, textDiagPrinter);

    // Initialize CompilerInvocation
    std::shared_ptr<CompilerInvocation> CI = std::make_shared<CompilerInvocation>();
    auto compiler = CompilerInvocation::CreateFromArgs(*CI, args, *pDiagnosticsEngine);
    if (!compiler) {
        errs() << "Error: Could not create compiler invocation.\n";
        return 1;

    // Map code filename to a memoryBuffer
    ErrorOr<std::unique_ptr<MemoryBuffer>> FileBufOrErr = MemoryBuffer::getFile(argv[1]);
    if (!FileBufOrErr) {
        errs() << "Error: Could not open input file " << argv[1] << "\n";
        return 1;

    std::unique_ptr<MemoryBuffer> buffer = std::move(FileBufOrErr.get());
    CI->getPreprocessorOpts().addRemappedFile(argv[1], buffer.get());

    // Create and initialize CompilerInstance
    CompilerInstance Clang;


    // Create and execute action
    CodeGenAction *compilerAction = new EmitLLVMAction();
    bool executeAction = Clang.ExecuteAction(*compilerAction);

    if (!executeAction) {
        errs() << "Error: Could not execute action.\n";
        return 1;

    std::unique_ptr<llvm::Module> module = compilerAction->takeModule();
        errs() << "Error: module is null\n";
        return 1;


a.out: /usr/lib/llvm-12/include/llvm/ADT/IntrusiveRefCntPtr.h:82: llvm::RefCountedBase<clang::DiagnosticOptions>::~RefCountedBase() [Derived = clang::DiagnosticOptions]: Assertion `RefCount == 0 && "Destruction occured when there are still references to this."' failed.
Aborted (core dumped)

Valgrind output:

==881080== Process terminating with default action of signal 6 (SIGABRT)
==881080==    at 0xC0B700B: raise (raise.c:51)
==881080==    by 0xC09692D: abort (abort.c:100)
==881080==    by 0xC096728: __assert_fail_base.cold (assert.c:92)
==881080==    by 0xC0A7FD5: __assert_fail (assert.c:101)
==881080==    by 0x442B94: llvm::RefCountedBase<clang::DiagnosticOptions>::~RefCountedBase() (in /home/es21btech11022/a.out)
==881080==    by 0x44273F: clang::DiagnosticOptions::~DiagnosticOptions() (in /home/es21btech11022/a.out)
==881080==    by 0x441803: main (in /home/es21btech11022/a.out)
==881080== HEAP SUMMARY:
==881080==     in use at exit: 591,201 bytes in 3,286 blocks
==881080==   total heap usage: 49,898 allocs, 46,612 frees, 61,756,943 bytes allocated
==881080== LEAK SUMMARY:
==881080==    definitely lost: 22 bytes in 1 blocks
==881080==    indirectly lost: 0 bytes in 0 blocks
==881080==      possibly lost: 32 bytes in 1 blocks
==881080==    still reachable: 591,147 bytes in 3,284 blocks
==881080==         suppressed: 0 bytes in 0 blocks
==881080== Rerun with --leak-check=full to see details of leaked memory
==881080== For lists of detected and suppressed errors, rerun with: -s
==881080== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
Aborted (core dumped)

Sorry if the post is too long. Any suggestions for the same would be appreciated.