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

    <tr>
        <th>Summary</th>
        <td>
            Clang does not check constraint expression is bool after substitution
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            bug,
            c++20,
            concepts
      </td>
    </tr>

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

    <tr>
      <th>Reporter</th>
      <td>
          ilya-biryukov
      </td>
    </tr>
</table>

<pre>
    ```cpp
// clang++ -std=c++20 ./repro.cc
struct X {
    constexpr operator bool() {
        return true;
    }
};

template <class T>
constexpr X check(T) {
    return X();
}

template <class T>
int foo(T) requires (check(T())) { // <- must be an error, implicit conversion cannot be used
    return 0;
}

void test() {
    foo(0);
}
```
see https://gcc.godbolt.org/z/Exa5srhKa

Standard mandates atomic constraints are of type `bool` and gcc actually checks for this, see the Godbolt invocation above.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJyFU01zmzAQ_TXismNGiPB14NDEcQ89NodchVgbNTKikvDE_fVdgZ24TTplZMvsyvvevn3qbH9uWcnXpaaJ8S3jX5jY0QJl5Hhg4p4WbHzoWb5V66vgkNIJh5OzqVLrv3xwswrwDKy6XyNAj7KjD_g6ObATOhmsg85aw0TNRPPn0fg4DLMbgUohy29yrNpeuNGPa2L9DnicjAwILH8gyt7DE8sf19w7-jOoAdUL4T59AL6APq-k3su_Yf4XR48B9tZeqzv8OWuHHihwA7tUX1bEh4vMVG4Dx9kH6BDkCOicdUw8gCY8rXSIGp7QeW1HUHIc7XJy9th_aIH_i_zJ6h4C-vCZ8Ctz_nnvV3dchowIQwiTZ_nFJgel0oPtO2tCah35ZfeLPo-vsvBu-CZvSXwPcuyl6-EYd2ID5IejVqtJnCQVKeQQ7B7CeSKlS76YpeQkTA8EBVKFWRpzXsfpibuDMGgfBYvkwoDwdaUDejxZJUPUTXb2hGmCbVaWvM6KouJJ3-Z9kzcyCToYbB-i3aG3RCtKvNS_YQbRRuiXKWi_mBjkPqADP3eeSswRKJmdaf8SSIdh7lJlj_RizOm6bejy_EBFE9lp72ekFnZFJbIqGdqeF3WG1V25l5WsG5U1TdYVTdWUTVcXdZEY2aHxLSvoOopuJtlFVIC2tyt6E7Kjwin4GCm2iW4FF4JUqDm1L5o0wxLvcr4XsmkEVzW743iU2qSRZhxq4tqFMQF5Shrtg39P0lXQhxFxYUP15RwG61ptznLTaXeeX-wpWVpsl_5-A_yiU6E">