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

    <tr>
        <th>Summary</th>
        <td>
            [Sema] Memory leak in `SemaOverload.cpp`
        </td>
    </tr>

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

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

    <tr>
      <th>Reporter</th>
      <td>
          lux-QAQ
      </td>
    </tr>
</table>

<pre>
    

### **Description**

Hello, I've observed a memory leak in `SemaOverload.cpp` that occurs during template overload resolution.

My investigation **suggests a possible root cause** related to the lifecycle of `DeductionFailureInfo` objects. **It appears that** these objects, created to store details about why a template deduction failed, are allocated using placement `new (Context)` but are not explicitly deallocated when their owning `OverloadCandidate` is destroyed.

**If this hypothesis is correct, it could explain why** a definite leak occurs for members that perform their own heap allocations, such as the `SmallVector` within `clang::ConstraintSatisfaction`. The destructor for `ConstraintSatisfaction` **would presumably not be called**, which would in turn orphan its internal buffer, matching the behavior shown in the ASan report.

---
### **ASan Report**
[build2.log](https://github.com/user-attachments/files/20628340/build2.log)
[build1.log](https://github.com/user-attachments/files/20628341/build1.log)
This ASan report clearly shows the leak originating from `MakeDeductionFailureInfo` during the handling of unsatisfied constraints.



```cpp
==386608==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 7992 byte(s) in 37 object(s) allocated from:
    #0 0x55c8fab23dc3 in malloc (...)
    #1 0x7f81bb63dbcb in safe_malloc (...)
 #2 0x7f81bb63dbcb in llvm::SmallVectorBase<unsigned int>::grow_pod(...)
 #3 ...
    #7 0x7f81c86b806f in clang::ConstraintSatisfaction::operator=(...) /home/****/llvminstall/clang/include/clang/AST/ASTConcept.h:36:7
    #8 0x7f81c942c8fe in clang::MakeDeductionFailureInfo(clang::ASTContext&, ...) /home/****/llvminstall/clang/lib/Sema/SemaOverload.cpp:804:25
    #9 0x7f81c9952e56 in getPatternForClassTemplateSpecialization (...)
    #10 0x7f81c9952e56 in clang::Sema::InstantiateClassTemplateSpecialization(...)
 ...
```
---
### **Trigger Context and Build Failure**

The ASan reports are generated during the build process itself, specifically when the newly-built Clang attempts to compile tests for `libcxx`. The sequence of events is as follows:

1.  `ninja` starts executing the compilation command for a specific test file, for instance:
    ```sh
    [1980/1983] Building CXX object libcxx/test/tools/clang_tidy_checks/CMakeFiles/cxx-tidy.dir/hide_from_abi.cpp.o
 /home/****/code/llvmleak/llvm-project/build/bin/clang++ --target=x86_64-pc-linux-gnu ... -c .../hide_from_abi.cpp
    ```

2. Upon completion of the `clang++` process, LeakSanitizer (linked into `clang++`) runs its analysis and **prints the memory leak report** to the console first.

3.  After the ASan report is printed, `ninja` detects that the `clang++` subcommand has terminated with a non-zero (failure) exit code, and **then prints its `FAILED` message**:
    ```
    FAILED: libcxx/test/tools/clang_tidy_checks/CMakeFiles/cxx-tidy.dir/hide_from_abi.cpp.o
 ```

4.  These repeated failures cause the entire `ninja` build to halt with a final status:
    ```
    ninja: build stopped: subcommand failed.
 FAILED: runtimes/runtimes-stamps/runtimes-build /home/****/code/llvmleak/llvm-project/build/runtimes/runtimes-stamps/runtimes-build
 cd /home/****/code/llvmleak/llvm-project/build/runtimes/runtimes-bins && /usr/local/bin/cmake --build .
    ```

---
### **Code Analysis**
[clang/lib/Sema/SemaOverload.cpp](https://github.com/llvm/llvm-project/blob/main/clang/lib/Sema/SemaOverload.cpp)
The issue appears to be a memory management mismatch. Allocation happens via the `ASTContext` arena in `MakeDeductionFailureInfo`, as noted by the `FIXME`:

*File: `clang/lib/Sema/SemaOverload.cpp`*
```cpp
//...
  case TemplateDeductionResult::DeducedMismatch:
  case TemplateDeductionResult::DeducedMismatchNested: {
    // FIXME: Should allocate from normal heap so that we can free this later.
    auto *Saved = new (Context) DFIDeducedMismatchArgs; // <--- Allocation
 //...
```

But the corresponding `Destroy` method is a no-op, which also contains a `FIXME`:

*File: `clang/lib/Sema/SemaOverload.cpp`*
```cpp
void DeductionFailureInfo::Destroy() {
  switch (static_cast<TemplateDeductionResult>(Result)) {
  //...
  case TemplateDeductionResult::ConstraintsNotSatisfied:
    // FIXME: Destroy the data?
    Data = nullptr; // <--- No deallocation
    break;
  //...
 }
}
```

---
### **Questions Regarding a Fix and CI**

I would like to contribute a PR to fix this and have two questions:

**1. Fixme:** The `FIXME` comments suggest using the normal heap. I could change `new (Context)` to a standard `new` and add a corresponding `delete` in `Destroy()`. However, I am concerned about performance implications and consistency with Clang's memory management model. What would be the architecturally correct approach?

**2. CI Coverage:** I am trying to determine if this is an issue specific to my local build environment, or if it indicates a potential gap in the CI's test coverage. The leak is consistently reproducible for me with the configuration below. Given this, I am wondering why the leak might not have been detected by the official CI pipelines.

---
### **Build Configuration**

Here is the full CMake command I used to configure the build that produced the ASan reports:

```cmake
cmake -G "Ninja" \
  -S /home/****/code/llvmleak/llvm-project/llvm \
  -B /home/****/code/llvmleak/llvm-project/build \
 -DCMAKE_INSTALL_PREFIX=$HOME/ollvm \
 -DCMAKE_INSTALL_RPATH=$HOME/ollvm/lib \
 -DLLVM_ENABLE_PROJECTS="bolt;clang;clang-tools-extra;cross-project-tests;libclc;lld;lldb;mlir;pstl" \
  -DLLVM_ENABLE_RUNTIMES="all" \
  -DLLVM_ENABLE_Z3_SOLVER=ON \
 -DLLVM_FORCE_BUILD_RUNTIME=ON \
  -DCMAKE_C_COMPILER=/usr/bin/clang \
 -DCMAKE_CXX_COMPILER=/usr/bin/clang++ \
 -DCMAKE_CXX_COMPILER_TARGET=x86_64-pc-linux-gnu \
 -DCMAKE_C_COMPILER_TARGET=x86_64-pc-linux-gnu \
 -DLLVM_DEFAULT_TARGET_TRIPLE=x86_64-pc-linux-gnu \
 -DCMAKE_CXX_FLAGS="-O3 -march=native" \
  -DCMAKE_C_FLAGS="-O3 -march=native" \
  -DCMAKE_LINKER=/usr/bin/ld.lld \
 -DLLVM_LIBC_FULL_BUILD=ON \
  -DLLVM_ENABLE_LLD=ON \
 -DLIBCXX_USE_COMPILER_RT=ON \
  -DLIBCXXABI_USE_COMPILER_RT=ON \
 -DLIBCXXABI_ENABLE_STATIC_UNWINDER=ON \
  -DLLVM_PROFILE_GENERATE=OFF \
 -DLIBCXX_INSTALL_MODULES=ON \
  -DCMAKE_AR=/usr/bin/llvm-ar \
 -DCMAKE_RANLIB=/usr/bin/llvm-ranlib \
  -DLLVM_ENABLE_OPENMP=ON \
 -DLLVM_ENABLE_LIBUNWIND=ON \
  -DBOOTSTRAP_LLVM_ENABLE_LTO="Thin" \
 -DLLVM_ENABLE_LIBCXXABI=ON \
  -DLLVM_BUILD_DOCS=ON \
 -DLLVM_ENABLE_DOXYGEN=ON \
  -DCMAKE_BUILD_TYPE=Release \
 -DLLVM_BUILD_LLVM_DYLIB=ON \
  -DLLVM_LINK_LLVM_DYLIB=ON \
 -DLLVM_ENABLE_RTTI=ON \
  -DLLVM_ENABLE_EH=ON \
 -DLLVM_ENABLE_EXCEPTIONS=ON \
  -DCMAKE_BUILD_WITH_INSTALL_RPATH=TRUE \
 -DCMAKE_SHARED_LINKER_FLAGS="-Wl" \
  -DLLVM_USE_SANITIZER=Address \
 -DLLVM_TARGETS_TO_BUILD="X86"
```

---
### **System Environment**

* **OS:** `Ubuntu 24.04 LTS on Windows 10 x86_64`
* **LLVM Project Version:** `aaec9e5f5b1abb79bda62ca7cb25258acfb1acc3`
* **Host Compiler:** 
``` shell
Ubuntu clang version 18.1.3 (1ubuntu1)
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin
```

### **Steps to Reproduce**

1.  **Initial Build Attempt:** Configure the build with the CMake command provided above and run `ninja`. The build will likely fail midway through with a `subcommand failed` error, because host tools cannot find newly-built shared libraries.

2.  **Set Library Path:** To resolve this initial linking issue, set the dynamic library path to point to the build's output directory.
    ```bash
    export LD_LIBRARY_PATH=/home/****/code/llvmleak/llvm-project/build/lib:$LD_LIBRARY_PATH
 ```

3.  **Resume Build and Trigger Leak:** Run `ninja` again in the same terminal. The build will now proceed to the `runtimes` stage. It is here that the `clang++` compilation commands will first cause ASan to print leak reports, and then cause the build to fail again.


</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJy0Wltz6riy_jVeL11QYAcCD3kwt7U4m1wGyExmv1Cy3WDtJSRvSYYwv_5USza3kDWzzpypSgUwUqvv_XULZgzfSMSHoDMIOqMvrLS50g-ifG_8Ev_yJVHZ4SFoxfQXRv4PgjAOwniEJtW8sFxJ_8Av-4ZCqCAcwjQI73cIKjGod5gBgy1ulT6AQPYduISg21rglj3vUAvFsmZaFEG3BTZnFlSaltpAVmouN2BxWwhmEVS1FjQaJUo6u-mPfTwAlzs0lm8YPa6YNOVmg8YaYFAoY3giELRSFlJWGvRrQCMRz8AqsDmC4GtMD6lAUGticoRZmRLNCeOi1DiVa0WMquQ_mFrTrI6aWmBFgUwbJ0JF2-ZosF5Kakk11ocZqzRChpZxYYAlqrSwzw_ATgJn9dmwZlxgRhSYRmBCqNTRKQ1pqBAsxS1KSwxL3EMQ9oZKWny3QdgnbpPSup1SWcD3QvCUW3GADE-k9jlKYphrUHtJZINuqzbPkMmMZ8wiEeMGMjRWqwNmzdo9nBLWYHNuID8UikTnhtamSmtMLTHPLaSqFJnjgXFJAleqYpDhmktu0btI5QNrpclzEqwUCwXqtdLbE6eQIytqlXAlnZ5NmebAjLMoedqWCfErplZpEmDPbe5dMBVMboIoDqJ4qKSxmnFpF8xys2ZO80G31YRljl7ikig4noJu69MNlUvsnaSFRlNuWSIOTvkJQsqEs6VX2hD2OU9z8Ku5BFtqCUoXOZPArQEuLWrJBCTleo2admyZTXMXGjlCgjnbcaXB5KQN7owI8YJJ0FgobSsTNRqNG3Hs1s3dulMcdwZJyUUWNoXaBJ1REPZyawtDegonQTjZcJuXSTNV2yCclAZ1g1nL0pxc0AThZM0F0mvY6oa96K4VhJMzgmH_7Iz2_9MZ7fqM9umMJfnimSIgFci0ODhNed_wrqb5hktmSaNrrbZk3Ef2HT8L_Tov5Qg5k5mgD2oNpTTODzhmkB59w9QR4v-6Lf9H6a4VB9EoiEZRr9tt9fz78Xz-PA-iGGbIvi-Y5Jb_gZoeZGgxpUA9S6TGUx1xCrBKmDXc9_shJAeLQdgzQdgnn4juqzRUPzsFPolMam_FAABBGLWg9d7ppL01S8IoSyPav3XrKbE0m02v3mp1G1rv9-teO0m6UZakCa02bI2rW1uCMApvrBdit_VReBapA2YwiIaldDWKYsMG0dgv22i1XxUquyYeAX088nZfnZX2ukmv1V3TWX8e8u47VaBmlC-i0fEQCMJJrrboPDQ--5uQAFway4QIwok_IpxwmYoyw7Mn8WLp_w-VTLGwzTyI4qgbRPH9ietezXX_Lkx7a7zi-lPXDHtnq_wZvgR0KWn830QQPAnCCVXq6uWiYEdxr3UXRHHYOXHfP3Lf74TY6RL3G7QvzFIemyg9FMyYZVXjFgWmnAn-R123P_pX6wbBM0Edb-7dlLiXljOLPzjj4gjvLceo_DRNLjXfbFBDpVJgMoMBpRuoDHAOgpaX-de4yrtBSQ6F2Xn6cBkLCq1SNIayPYq1K1_E8ZpTpTgcCzNI3ItDg_ZYGJICgHS6LawhPJGqbcEFgnWIp6pRgifp-_uxiBn8b4kyddgGd5RJqUAzWi6E2hufBoJW3G6CwxJc_odRyjOWkSD4jmlpa-79id5wqdpuSSl0Ljvy75gBStUkFX3nPEymeJZwauWbvH7SGbT7Paoa7X4vCjojr2o6dvj2VuUxqEQLJ3QGvSglTO25K8uzwyrNMf1Oz4YUM5OqYqTv7w36uplxTdHAM1xRDlyxhJNXN5VPJp_ESapcRFO4UMKt3jYKrXx69WWIXrk8BdIgCAfQaFimN2iDaPTe6666d40ibQguy_fGRpbkjNBIfaB-ZOtaXd5QYRNeC6__QqAzhVrXsOfsbDJi5WdkiovqQlEnuPzuc6z6uJPyhi6l81BgkokDQTsyt9dKoanQuVPPUb4-gxU1vKbCqATCmmtTI5OoCRCvLepr5ELO6Wh76HvukL4aVpjwtrimTGqvzAkKot5SlSeoy20ODKSSjT9QK5J_XYdxH_DdwdTM-exJSEthWElKegi6rUk8nY1HdNYWjWGbOgt89O3qc7Uhiv9x7730krsmUPwbJMX6DqQS2PheyKkQpeUaL9TsE5RVkDNha72tOcFRY5ktzeeyehpRXNEwVhUFZvTgzDC-r3EV-6QbXUrLt07a-m3DWLYtLp54sn8_TH_iNGIz_afOTLg04Gp1FxzkJfMSRhOnXLJl3xEalejN2xnhdgEbqgwhrkL3HOn_tUL_ZwDdAbiP4gpFRLfsPBP-yUkVckfgxpR4aqoVtU7HKcKWSbbxLe-WG9cPNSE-9oCQ0z5pYMdZnR3OAFG3RSVZsmoO8QOs71KAoc4NM0gONa3J9O1xTF_X9TIIYwpQ8t5TIvoTSYn6rZ7AabeGsSkzCDWQOTI5R1MK61GPe4jZY6WGOiB_euMTGuvjM7gfHOEX8QJe3CiGRe661Lp38N2SVHrLhG_DjfIZeU9troS1RvQjAeJC1x7LSqoyYbxgO8wgiEbwYWgBo8n0isFYb0wQDWqmgmjYaDTOjF5V7aPyruJiUNqqAmmNplAyq2YcIz_L8Gnc5ipzmAikaqji1J8zYQhjScsoTtk_7QU7xTO46ZSV7TzPYc9h-spgZs9tmpMiKTnzdJUyY4No-KkbjIOwV70P--eUftYJT52UeVJVN8WdN33iSZUAziIZsyyIJtXKEbPM-0QpRGH1R5M_qdPgqrI7ACSaUm50g__gfkQK9v__SrL8pUTjRkkwxw3TzlEYTPi7gwPD6TnYn1aTG8G_o4fh0mqelJay1cucHq35uw8CD0V2CHav4L_1IefuE4QEvSf8fesQsodOy8uk47C2w-7VfLOaAroW4RSLTZhWw7Y0Z3KDn84GrSLEbpnMmM6qVS5FygxYlgH7GDIZCqxmgfI8hJw7um7jm9rjzk-rpsC2pJYUNbXxftJZjfGoFQC-LQSvhnfuVAKJ3FiU6cFjjqEPpXtzK_-rDEUTfnNpx8mbeDjDdJpzQomldn1UNYekkqIVo0w5Odd72IThFIZqh5qQ3FH7jn2rD07FygFPApIIvJp2OsNW5erU-CjYHsCV7woAodxxrSTxTFqhXmgN3AKXGQmPfkptCYQxARtW1KM88rd741uptGLPt3N-lm5O-rLiQAhPq6xM3bTbj0-9Eiv4veabUvsqmaBQ-yZ85TvXYXJzNNdeyQxdm7rPD6dJ2ZZvcuvmmM6NE0R5mktV5VGt15zabdJmwQsUXKL54QzSN9LDc9Yu7xQ0oQFHfF0KAQ4PHzvOKZTGT9Rr4fCst_YzY6cQWnTVmZ9C75h9CWIFrbiCWl8hCMMnh2TDEILO0GWXxuJvYED6eKI0-LtosibVGA0f43-NV9OnxTKezVYv8_Fk-uamV3ffnh_HQThR50dfr5-_xMtvH5f7-nXaNJv9-rgaP8WD2Xj1Mn_-n_FwuXC7wkRRMajwZPXacG1NA9-tZvRMK2NqARpuUBFEA2qFREpvROb_J0E02ApOqb8wVlyo_oKD-evTcvo4rjhwk6vPlv47Wi2eZ7-O50E0en66EmjyPB-OV4PX6WxU07xYdtTWcDV8fnyZzhyZI0o_6_Sv1Tt8e_uzLdVw4AcbV8t4_nW8_GRscL3xZ7c5DYzGk_h1tqy2rJbz6cts_BcPfHtbTWbx18oKjecIGltKvkE0kszyHV5apWbz5_fMpk__uqVGkTXFeSQ4iWbTwXA1eZ3NvF2v7XnuG7Orrxsj2vz2tnpdjE_anC8_0HCr4sH0hwvP11UHLpbxcjpcvT79Nn0aXblkzdvL_HkynY1XX8dP43m8dA45mXxgsY7fx-fR68xFwg23jW8pjZIJ09fWnMdPs-ngk-WaybNscKXF55fx0-PLrfCq1TwdeImvmRw8Py8Xy3n8srpYvnz23rHMiYPwU6JetzeV6EN69Dxc_ICv0fPb71_HT7dV5yksf38hA8xRIGHhSzJ-iQ-j373yPnJCvvvZmquktlzeFqb6fvztB5vHb8Pxy3L6_PSJJ3hef5suv33I_Mv56_jaGxbf4vl4VAXeRcT-divXUhgs4qfpcvpv59Vxlmk05opVn2MWq-XzMTSDMHzrdYMw_KsQfXEwFrcwPgdVJ8hAuM1_fl6ckFzQbb0mpbQlhHfN1h3MlgtQEn7jMlN7A-0W-GxXHX2kQUzDi69a8CtqU10SHakyhmkfO-tO0mZJct9PMtYNU3afJmEn7PRYuk7aLE2ja8LflLEw9HN7fUbxTAdgchQiaMUV577I7DwT0O41201SSa9duu_b1fykGjPHcCN_u_mKRpZ56EyrCmX4OzUz_v4HsxF3d44XOeCDZT7YxGLhJjXzCoJe3Iq4KwX_MwHJHcb1uC_2dxgn8Yc3YNwRwF5iv0KrHc98U7FD1zvoUp5PMD1QrokI4fo0cXCDR9jybM8ItWpVbvJ6vBl0Wx8mlGQJ1Fq5hiZBPzPNyXwO4UDKJKHiNZfZxTWNyZlGag4TzTQ_4uDwqIsFWpi5bw_wwmx-1vUp_zuXXTVB4ZXWBJffCZi7hsNdFqEfbGQHybY8rQ47QMFIZwoKxaWt5-_VBPLegCptUVrI3N2x0ocP48SEHW9k8N2N4ynLTQfzeP776ogW_-4oVPDEyXx3TfzjFDs6am2Optxi5UBkpfp-buZmALUK55e-AGzD-PEXEoZtsb4UEB_cRKq9vy85_TIo6LaOc1t_JUZ92NTdUuTo3PXTu4gbV2XGH-QuQqohvGtNyGKaLHZ2h2Lqqwh3CXGa2B_H886dnXiVh33JHqKsH_XZF3xo39_1w_Zd2O98yR_STvu-307us4QlnbCbhf3WXSu6u-v3wqQV4t0X_hC2wk6r2-q2w0476jQ77TvsZu120lun7L7bDu5auGVcNMmiTaU3X5wrPrTvonbY_yJYgsK4X5SFocR97ahh0Bl90Q_ODZJyY4K7luDGmhMZy61wP0Vzs7LOCB7_yk_GvpRaPPz0aNoxZYJwUnG9ewj_NwAA__-mix4u">