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

    <tr>
        <th>Summary</th>
        <td>
            [MLIR] Project compiled using `gcc` links incorrectly to `mlir` compiled with `clang` causing invalid memory access.
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
      </td>
    </tr>

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

    <tr>
      <th>Reporter</th>
      <td>
          Jezurko
      </td>
    </tr>
</table>

<pre>
    ### Description:
```
/// Parse a type list.
ParseResult parseTypeList(SmallVectorImpl<Type> &result) {
  return parseCommaSeparatedList(
      [&]() { return parseType(result.emplace_back()); });
}
```

(in `mlir/include/mlir/IR/OpImplementation.h:1153`)
Passing the lambda to the `parseCommaSeparatedList` function causes a runtime issue when `mlir` compiled with `clang` is linked to a project (such as VAST - https://github.com/trailofbits/vast) compiled using `gcc`.
The issue is that each compiler has a different order in which it stores `lambda-capture` attributes in memory. While `clang` stores the `result` reference first and `this` pointer second:

```
(lldb) print callable
((unnamed struct)) $3 = {
  __result = 0x00007fffffff2350
  __this = 0x00007fffffff30d0
}
```

`gcc` does it the other way round:

```
(lldb) print lambda
warning: `this' is not accessible (substituting 0). Couldn't load 'this' because its value couldn't be evaluated
((unnamed class)) $1 = {
  this = 0x00007fffffff30b0
 result = 0x00007fffffff2330
}
```

Because the file `OpImplementation.h` is included into the project it is compiled using `gcc` and therefore generates the `lambda-capture` the second way. But calling the lambda (from inside `llvm::function_ref`) uses `clang` compiled body of the lambda function (because it is inlined) that expects the reverse order. (What we believe happens is that the linker throws away the `gcc` compiled body because there already is one in the linked library). This causes the `.emplace_back()` to be called on the wrong object  (`this` instead of `result`) and an invalid access to memory leading to a crash.

What we believe might resolve the issue is using a virtual function in `parseCommaSeparatedList` instead of the `function_ref` argument.

### Steps to reproduce:
This bug can be observed using the packages from the `llvm` apt repository (`clang-16` `clang-tools-16` `libclang-common-16-dev` `libclang-16-dev` `libllvm16` `libmlir-16-dev` `mlir-16-tools` `llvm-16` `llvm-16-dev` `libclang-rt-16-dev`) and compiling VAST (https://github.com/trailofbits/vast/tree/gcc-build) using `gcc`*. Then running `vast-opt` on a simple input such as
```
module attributes {dlti.dl_spec = #dlti.dl_spec<#dlti.dl_entry<!hl.int, 32 : i32>>} {
 hl.func external @minus (%arg0: !hl.lvalue<!hl.int>, %arg1: !hl.lvalue<!hl.int>) {
    %0 = hl.var "res" : !hl.lvalue<!hl.int> = {
      %1 = hl.ref %arg0 : !hl.lvalue<!hl.int>
      %2 = hl.implicit_cast %1 LValueToRValue : !hl.lvalue<!hl.int> -> !hl.int
 %3 = hl.ref %arg1 : !hl.lvalue<!hl.int>
      %4 = hl.implicit_cast %3 LValueToRValue : !hl.lvalue<!hl.int> -> !hl.int
      %5 = hl.sub %2, %4 : (!hl.int, !hl.int) -> !hl.int
      hl.value.yield %5 : !hl.int
 }
    hl.return
  }
}
```
by calling `builds/ninja-multi-default/tools/vast-opt/Debug/vast-opt <input-file>` (it is also possible to pipe in the input).

It might be more beneficial to use a debug build of `mlir` for observing though.

### Observing the bug:
```
$lldb -- vast-opt <input-file>
breakpoint set -f HighLevel.cpp.inc -l 5684
run
step
```
Now we are in the lambda initialization:
```
(lldb) print this
(CustomOpAsmParser *) $1 = 0x00007fffffff30b0
(lldb) print &result
(llvm::SmallVectorImpl<mlir::Type> *) $2 = 0x00007fffffff2330
```
if we now `step` into the call of the lambda and print the pointers again we can see the values are "swapped":
```
(lldb) print this
(mlir::AsmParser *) $4 = 0x00007fffffff2330
(lldb) print &result
(llvm::SmallVectorImpl<mlir::Type> *) $5 = 0x00007fffffff30b0
```

### Additional notes:
The lambda mangles to `_ZN4llvm12function_refIFN4mlir11ParseResultEvEE11callback_fnIZNS1_9AsmParser13parseTypeListERNS_15SmallVectorImplINS1_4TypeEEEEUlvE_EES2_l`.

The memory layout stays the same (`lambda-capture` is `const`). Probably the easiest way to observe this is by printing the memory at the address of the `callable` variable in the `function_ref` constructor and then printing the memory at the runtime address of the capture in the lambda call.

*On Ubuntu run in the root of the repository (at  the moment the `master` branch will not compile with `gcc`):
```
$ git clone https://github.com/trailofbits/vast.git
$ git checkout gcc-build
$ export CC=gcc
$ export CXX=g++
$ cmake --preset ninja-multi-default \
    --toolchain ./cmake/lld.toolchain.cmake \
 -DCMAKE_PREFIX_PATH=<path to llvm & mlir config>
$ cmake --build --preset ninja-deb
```
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJy0WFtv27gS_jXMy8CCTNmO_ZAHJ7GxOafbFk13t9gXg5LGFjcUKZCUXe-vPxhS8i1Ouj04JzAQm5fh8JvbNxTOyY1GvGPjezZ-vBGtr4y9-xf-3doXc5Obcn_HeBY_8IiusLLx0miWzVn6yNI5m6TdJ_7ky_iBz8I6BAF-3yAo6XwSV4TxL-ha5aGh71_3DX6QzjM-fa6FUr9j4Y19qhvFsgeaZNkCGJ_YsIfxGbDb-ygLwKJvrY6CHkxdi2dshBUey05kv5D-6JJ8wsaPNB7lnAkIh_FpPCjBulGiwFUuipe4gT7ZPbDbx_itu_Lt43UoOkCmUgObpLWSlvGl1IVqS2R82Q08fWF8-amh-2KN2guCN6lYNh8OxxlJ47MeOeek3oCvEJSo81KAN-EXm6RvITBJYd3qgoRCIVqHDgTYVntZI0jnWoRdhUcNJykUpm6kwhJ20lc0USihNzQjHSipX7CkgwU01vyFhQfGp64tKhAOfp8_f4UBVN43jnwk-MJG-qrNk8LUjC-9FVKZdS69Y3y5FS6Y9HBmG67IJummKNgk7Zzma9UrKx34SnhAUVT9LguVoGuVcr1Gi9qDsSVakBp2lSwqkB6cNxYdCY7QDQrR-NYiXUt4b2XeenS0pcba2H0Cf1RS4dn1Oxkd4p0_TlKwGI4tENbSOg9Cl7TAV9LRdGOk9mjBYWF0eYyc6_EzVarMCZLGSu2hEEqJXOFhmvFpq7WosQTnbVv46JjA-CgDlj2eRsdqFZUM4-n3NE3T23X849k4PS4jVa8sytIy_UdO3psLSkMg-oCR8RVa2Ik9WNP-9MWjmeLkTlgt9YZl8wOu_JZcQRsPoijQOZmTscgRc-elbz25EcVOAg-mVaVm_NaDMqIE-taJyDHEBEjvYCtUi1AcF-cISIMUS9fgL5Rw7oj-8BL9N0HNe-TfsU72j4C_7_QnuNedu17JJTF0u9RTgtRd3ugDWHqafysGgz-TLXFtLMIGNVJ-OQTC64CiiejtZP4E7tvoyBfZi_Hp2poapHayjKLUtiY_yeZ90lpZXMckCCF5ncbjQWGqU2DWp7IPSY_x6dHKEQYlNZYkMWaS7w0WPt7G4hapbIX8kdDeP2jJDiFHJXGLUImmQe0OeSgcSTnRgq-s2TkQ5PEdNB2A54rmR6NZBKEsinJPAo1GSkAHkSUomVth98GNv5I7dSm8E3-tRhH8hnyXAMcSTBS4s0ZvwOTB3nSxkwQltfMoSkLwNK8RQmR6oUHqrVCy7GKNDohZEhSKMliV6kFhhauSU_-8RK-Wm8qT2xu1jV57yOrR6QRspfWtUEcDxvL5Tn07Ub_D5cJ5QNhNS_GQnFfmntc8e2zCpSw21pRtgYdcFUDP2w0UQhOoJndot4cYCUEkihexQQfBl_uYIEemkxu6bmOc9ARXxD048GA4oQWHn94Y5Y6DSuZxvDB1bfRgOBmUuL2cvBylY09FUEk_X9SPhOP6hWpbn5wcf107zvrjRO8d0bcJjFD7GZ_-ZPFfeovEhzZFMchbqcoY62cpiPE5BQBqoi66m6LtA9MEHzAaBDhJiQ-kbloPHSO5mjxrU7YKT-s-u70vlZdJqVauwSKmcp6djrHs4WQEtbf7MDSsVCK1Z_wBMg5Uo2TGWbagz-1pQahUQo4J-N2j1UIBG6W11K0LbsHHwm7SUOKCSBXq0dkJ2YIOiSuHP1x5xpMp5MdpuFalkq2wwDi36BiPKr8j6bKsdcKGvTCL606n9EeiLkTwXgTZTRbSrwrhfBT-4Xfa_9V8Cf9_qOMgNgn9SDyH8XH2WsvhT2o5elPL7H-iZX_OuD_HtXlApzP2qBM7PXO1kx-zd-QGY6sWk71EVfbHzF9D1dOMblNsi_qhIwl5g43k-0N9Z5M0RDEFuJb6LzGoW-XloMS1CP3bMqaeGP4hfvnyEfN2czIELHsIYTwgVkM2oUzEp7GCC-UMNKYjfd5AI5tD5QzbqGCe5von35WeHKEmEpOjxrUspFC0vw2daklKQFC-K4V9R7Q2tsv8MembdlO9UUs-nSxDqhxvd8ojIrwwGMDbt47gWhQvoYkAhx4Ga_hFbqoPuEWVFE2TSF3AQMF4Mh3FDbbtLOc8NlcP_2h2VJaFPRKOSJukll4KJf8W73f5F2Q9MIl-6qF13tSfmrmrQ7NPuWZ-RpLfIsSv5B7b_uN8zxBfPxYEc4W547NBfzB_n2Wf30-uCR1tduQEAcRAMzrWTJ5-wTapEPZIYN_wORAbQT0oBvbgMDKeEI8uYM84dzsilCXj_L8D-3jna3CP3r_1_w_u8ft2vv5S0sfQvCwluZ9Q1OChO2FjB8RroTcKA2tjk3T158dR4D78lPo9LT-OSMnh8OTRabFdLIZDsiGR5tVaP_358Xm4mh3gG2Znz1KLLx-fV8PxxfWfaM-I1iwWi8VvartYLRbPfKWObxZHlXuuLPaGiIkX-8jgnaixo4SveygZex2jXcfFE_hsTS5yFbsLFE6i86G_9qYnprHpJM66jzbtM1GnQ9exiLK0ROSPlPnwzjBJYSuspO99brjCqINetiU4-vZQv3dg_-J0cXB334skRLpcpNf5Jw2_5a32LYnq11tjfC_qnGULD1ELQ7y_v0UtnMeQ0XMrdFHBTqrgY32Hdnjy6mnn7J30DRvpoVDUtf0U5U020l8IqbB4Id84cuDDPH5vjPXw8MCyR9Lq1cS3bzTD-D19DrNFLV4QBoPGIhWNK5UY2PjhWPMHoSMoKkpYCePLsJ_xpVJlcphJotTjxsHjw6_zfy9Wn78slk_fVp_nX39h2SPLHhrhK3JLCkpKK0BxSF6zlptDYTvVM5bdC31LzC_AvynvsnKWzcQN3g0n09Esm8yGtzfVXSpwVGbDAme34wLHY0yHEz6ezkbDWT4ReXkj73jKs3TMR8NROhzfJuN8ko1uM1Eix0yINRulWAupEtI5MXZzE3rTuwmfDac3SuSoXP9Obu9Cl5S3G8dGqZLOu-M2L70KL-q_fnj6wsaPFLeh7X7zgYW6_fA-Y6zFwqt9l9Z-_CJbiCirb9D7qAt9enLTWnX3jm-G7B7_Dbq3IMaX4drkrOHm_wkAAP__vJtydQ">