Issue 175895
Summary Behavior discrepancy with `enable_if` attribute in overload resolution
Labels clang:frontend
Assignees zyn0217
Reporter zyn0217
    Consider

```cpp
using int32_t = int;
using uint64_t = unsigned long long;

struct wxuin_t {
 wxuin_t() {}
  wxuin_t(uint64_t v) {}
  wxuin_t(int32_t v) __attribute__((enable_if(v == 0, "Except only constant expressions"))) {}
};

struct wxuin64_t {
  wxuin64_t() {}

  operator uint64_t () const { return 0; }
  explicit operator wxuin_t() const { return {}; }

private:
  operator int() const { return 0; } // #0
};

struct wxuin64_t_deleted {
  wxuin64_t_deleted() {}

  operator uint64_t () const { return 0; }
  explicit operator wxuin_t() const { return {}; }

 operator int() = delete; // #1
};

int main() {
  wxuin64_t uin64{};
 wxuin64_t_deleted deleted{};
  auto b = static_cast<wxuin_t>(uin64); // #2
 auto c = static_cast<wxuin_t>(deleted); // #3
}
```

https://godbolt.org/z/dWeq9dM63

clang rejects `#2` but accepts `#3`. The only difference is that the conversion function is blocked in different ways: `#0` is a private member, while `#1` is a deleted function.

I think this is counter-intuitive, and we should also accept `#2`. When checking `enable_if`, we should rule out inviable functions, which is supposed to include inaccessible members.
_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to