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

    <tr>
        <th>Summary</th>
        <td>
            [mlir] Dangling function object assigned to function_ref 
        </td>
    </tr>

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

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

    <tr>
      <th>Reporter</th>
      <td>
          peledins-zimperium
      </td>
    </tr>
</table>

<pre>
    /opt/homebrew/opt/llvm@17/include/mlir/IR/StorageUniquerSupport.h:134 returns a temporary object on stack:
```
133   static auto getWalkImmediateSubElementsFn() {
134     return [](auto instance, function_ref<void(Attribute)> walkAttrsFn,
135 function_ref<void(Type)> walkTypesFn) {
136 ::mlir::detail::walkImmediateSubElementsImpl(
137 llvm::cast<ConcreteT>(instance), walkAttrsFn, walkTypesFn);
138 };
139 }
```

/opt/homebrew/opt/llvm@17/include/mlir/IR/TypeSupport.h:46 has:
```
 44   template <typename T>
 45   static AbstractType get(Dialect &dialect) {
 46     return AbstractType(dialect, T::getInterfaceMap(), T::getHasTraitFn(),
 47 T::getWalkImmediateSubElementsFn(),
 48 T::getReplaceImmediateSubElementsFn(), T::getTypeID());
 49 }
...
104   AbstractType(Dialect &dialect, detail::InterfaceMap &&interfaceMap,
105                HasTraitFn &&hasTrait,
106 WalkImmediateSubElementsFn walkImmediateSubElementsFn,
107 ReplaceImmediateSubElementsFn replaceImmediateSubElementsFn,
108 TypeID typeID)
109       : dialect(dialect), interfaceMap(std::move(interfaceMap)),
110 hasTraitFn(std::move(hasTrait)),
111 walkImmediateSubElementsFn(walkImmediateSubElementsFn),
112 replaceImmediateSubElementsFn(replaceImmediateSubElementsFn),
113 typeID(typeID) {}
```
walkImmediateSubElementsFn is:
```
 33 using WalkImmediateSubElementsFn = function_ref<void(
 34       Type, function_ref<void(Attribute)>, function_ref<void(Type)>)>;
 ```

However, function_ref says:
```
/// An efficient, type-erasing, non-owning reference to a callable. This is
/// intended for use as the type of a function parameter that is not used
/// after the function in question returns.
///
/// This class does not own the callable, so it is not in general safe to store
/// a function_ref.
template<typename Fn> class function_ref;
```

Thus a temporary is stored into a reference object, which can lead to a crash.
Found by clang-tidy+clang-analyzer.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJykVkGPozgT_TXOpdQR2ITAIYd0Mmj68F1m-tMeVwaK4B1jM7bpVubXr2wIIdlJ90obRQnGfuWqV6_s4taKk0Lckc0z2RxXfHCtNrseJdZC2adfouvRiKFblbo-7wgtdO8ILVrdYWnwfX4h5VtHkijeEloIVcmhRkKLTgpDaPHyjdDiu9OGn_D_Svwc0Hwf-l4bt24J28csAYNuMMoCB4ddrw03Z9DlX1g50Aqs49UPwvYkOpJoT9Jo-oZhzBiAX-JEBXxwGk7o_uDyx0vXYS24w-9D-UVih8rZQhGaEZoD2T5f4An4z-gBjEQQmgVLQlnHVYWEHqAZVOWEVn8abAg7vGlRE5rtnTOiHBwSmhP2Bd65_OHfhZ0Oly02D9Cv534J9MMAvPEvBR862wc2w1ONjgs5Pr8_iPSl66WPdTKyhZCiAKm4dYQdDlpVBh2-EvaF0Owaa-7DvQ3kzj3CZu8yINvjYpyH8e8SNf3-Bw15B5bKSVJouX0kDEh8Zr2eJHcIhB3cuUfFO4QQ8rRoc1XPvrTO8Mr5fbyKCM2OgkuvQkLTeny8yQ4k6VI9SwOEZjPi4Hf01J_QvSiHpuEV_o_3oxhv579y-2q4cBepzjKCZLtY9pnCF7BsAfuGveQVfoJcAHwoL8fLzDXzkCwyvV6vp_xHnvM7Gn7H4QGWIl5y4pcRmoobmi6VFG3g7nOlawK204sFKIXHbMGjAloWcLSFD4kD8zGts50MRj7BTbTml5l8ioewPcwsXRUUsnLLSWZdPZ0M-g1DBS-n86UI4jiCdimse-yVtTtc_CFB2UeTSzP0M4qyT-aXxthMXzbzGGrywcnz2EkQj48PxmCwQp0-Eg9hxwdH-8VIMuV1rIV_eY08Xni9MabfuR5_e9p-1e_4hubeHlh-fhg4ocX4hb0CbBpRCVShZD3ZT2i4Z8WPlVZP-l15jgw2aFBVCE4Dh4pLyUuJa3hthfUs35n2WlU11tBoA4NF4BZci2EL0A3w2V_oueEdOjTgWu5AWFDaeUx9b5Q34yq8goWCnwPa8Dw1Ges72L2V4HElubVQaxx30-8q2L3E5aO3GsTsjlBwQoWGS7C8CSxYpw3-w8WbPEyuXO6o5RVVKN8VjG7cSuH5g9v1tR1umyhhRz9qz7jPzDVRY38VLvdWVC1UXIFEXk8ZNNy2k3-FHlQN5dm7o05PTtRnQp_HAVdcnn-hWa_qHatzlvMV7uI0z-lmy1iyandVmiYpwxjzvIoozZClURrXTUPpluVpvRI7GlEWx1EabTcblqyzTZ5UaYo8jtKybBKSRNhxIde-RVhrc1oJawfcbWOWspXkJUobWlhKx3aB-mbW7Pzyp3I4WZJEUlhnrwaccDK0vQGwOcKRq5P0Sp6lM_WfU48caLmpodVg5K51rg-VFNJ7Eq4dynWlu0s_M_499UaPZBfBc0toEZz_OwAA__8Txo-V">