[llvm] [IR] Simplify HasCachedHash with is_detected (NFC) (PR #159510)

Kazu Hirata via llvm-commits llvm-commits at lists.llvm.org
Thu Sep 18 15:09:22 PDT 2025


kazutakahirata wrote:

I've reproduced the failure with clang version 18.1.8.

I ran the two versions side by side:

```
template <class NodeTy> struct MDNode::HasCachedHash {
  using Yes = char[1];
  using No = char[2];
  template <class U, U Val> struct SFINAE {};

  template <class U>
  static Yes &check(SFINAE<void (U::*)(unsigned), &U::setHash> *);
  template <class U> static No &check(...);

  static const bool value = sizeof(check<NodeTy>(nullptr)) == sizeof(Yes);
};

template <class NodeTy> struct MDNode::HasCachedHashNew {
  template <class U>
  using check = decltype(static_cast<void (U::*)(unsigned)>(&U::setHash));

  static constexpr bool value = is_detected<check, NodeTy>::value;
};
:
:
:
    static_assert(HasCachedHash<CLASS>::value ==                               \
                  HasCachedHashNew<CLASS>::value);                             \
```

The `static_assert` doesn't trigger with clang version 19.1.1, but clang version 18.1.8 somehow thinks:

```
HasCachedHash<GenericDINode>::value == true
HasCachedHashNew<GenericDINode>::value == false
```

even though `GenericDINode` does have the `setHash` method:

```
 void setHash(unsigned Hash) { SubclassData32 = Hash; }
```


https://github.com/llvm/llvm-project/pull/159510


More information about the llvm-commits mailing list