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

    <tr>
        <th>Summary</th>
        <td>
            Clang should warn about `noexcept(noexcept(is_meow_v))` always being true
        </td>
    </tr>

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

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

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

<pre>
    Consider the following code (compiled with Clang 15.0.1). Clang is behaving correctly as required by the Standard here, but there’s a notorious bug in the user’s code that the compiler could warn about:

```
C:\Temp>type meow.cpp
```
```cpp
#include <iostream>
#include <string>
#include <type_traits>
using namespace std;

template <typename T>
void do_thing_good(const T& t) noexcept(is_nothrow_copy_constructible_v<T>) {
    [[maybe_unused]] T duplicate = t;
}

// USER BUG: noexcept(noexcept(is_nothrow_copy_constructible_v<T>)) is always true!
template <typename T>
void do_thing_bad(const T& t) noexcept(noexcept(is_nothrow_copy_constructible_v<T>)) {
    [[maybe_unused]] T duplicate = t;
}

int main() {
    const string cat{"cat"};

    cout << boolalpha;

    cout << R"(noexcept(do_thing_good(123)): )" << noexcept(do_thing_good(123)) << "\n";
    cout << R"(noexcept(do_thing_good(cat)): )" << noexcept(do_thing_good(cat)) << "\n";

    cout << R"(noexcept(do_thing_bad(123)): )" << noexcept(do_thing_bad(123)) << "\n";
    cout << R"(noexcept(do_thing_bad(cat)): )" << noexcept(do_thing_bad(cat)) << "\n";
}
```
```
C:\Temp>clang-cl /EHsc /nologo /W4 /std:c++latest meow.cpp && meow
noexcept(do_thing_good(123)): true
noexcept(do_thing_good(cat)): false
noexcept(do_thing_bad(123)): true
noexcept(do_thing_bad(cat)): true
```

The bug is accidentally saying `noexcept(noexcept(variable template type trait))`, when only one `noexcept` should be present. This mistake is *extremely* easy to make (as `noexcept(noexcept(arbitrary expression))` is commonly needed elsewhere).

The compiler could warn about this, for example whenever it sees `noexcept(noexcept(THING))` being applied to something that’s a `constexpr bool`. False positives seem quite unlikely, and the value of the warning would outweigh any potential need for rare suppressions.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJysVktv2zgQ_jX0ZVBDpmzFPvgQO3G7wGIPrYs9GiNpYrGlSJUc2tG_X5BynMfm0QQFDEk05_HNN8PhoPdqb4iWYrYSs6sRBm6sW35j6ho027_xgAf6MSpt3S_X1nhVkwNuCG6s1vaozB4qWxMIOa9s2ylNNRwVN7DWaPYwmY2z8UTIxfj0h_JQUoOHQdE5qlj3gB4c_QrKUQ1ln-x_YzQ1uhoaciTkGsrAccORuJZinonFwgOCsWydssFDGfagTNINntwDqQSQG0z6cILpoLJB13BEZwBLG1jklyK7Etnds8hOv7Rcx-3ZekttJ_Jr7juCluxxXHXds_Ln5b2AzJWpdIhs5WtlPTvCVuTXz217dsrsX9iM3nfsULE_SwQfKTXYku-wIvBci3z1MCCmttPIZwtRFrZnAweraqjtjhtl9ru9tXXKqfEMWyELYCEXYCzdVtSxkHPld8Zy4-xxV9mu3yVRFypWpabdQeTrZFsuQFyccAAApDpbtdiXtAsmeKrF7ErMrmALdei0qgaEV8D38C-uHiVGboTcwPdv119h9f2zyC8fwvoIwghSeUB9xN4Du0BCTj5AWolvcPZRcH-YQWUYWlRGyPn_rA_oh_KDCjluShk_pIxmHtfUoBE40iPyNZTWatRdg2_IfY3WHvHxtPImMh-Cj_lNX_JO-Xe07mSjn9naxFe--iiWFP27sZy1XsHybkRDib2TnCdKf4abU7G_j5onSq8xcy7ZF_rqc225infMp0qDkJvrL76Kb2O13dv49e80PlNjvKyEXAm5ikfb87mTg5BFPLdxPdj_3QpNTeMtjUdk3aD2r6g8k-jXfTyTj3uFpySm57ah4db0gFWlajKMWvfgsY-HXxTZ863rgE5hqQnOzTFdh-lCOjkvsnhlHxsyYI3uwRp6ZK_IwDfp_i0JOkeeDI9h2ygPrfKMPymiEvKSbtlRS7oX8hIIfQ9soY37Qs7RvwwSXanYoeuBbqMDr6w5g4vGK9u2CZshqqkG0p6Ow7CxGD-l6cWhAbhRPsZ6Yx3QLbadphQ3HciBYvBEr6Dcfvnrn8_3sEqKxGPXaUV1jNTbllJ60_zyaPKJo0Xs1TG81HdFkY1hE6sKOusVqwP56L6FX0ExQTBa_UxMrgFNnYahA-pAYG_SIkYVXR1TjDbwkdS-ATQ9dJbJsEKd2ErBOnQEPnR35PrxqF7m9SJf4IiWk-JiLvNilk1HzTIvy0mR3ciprMsix8l0Ps-RkGQ5KfNifjFSS5nJPMuzeZZN53I6rrNZkVe4kHRRZxezSkwzalHpsdaHdmzdfqS8D7QsJnKWjzSWpP3dCOuWUehTGfZeTDOtPPt7NVasaTnMoqcKfJDMF_Ok_C72hN3hPlenaWFIWTxpo-D0smHufOxJaUjZK25COa5sK-QmYji9PnXO_qCKhdykOLyQmxTKfwEAAP__NfOL2w">