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

    <tr>
        <th>Summary</th>
        <td>
            [Clang] Error on an `enable_if` attribute in `ADT/StringRef.h` in C++23 mode
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            clang:frontend,
            regression,
            rejects-valid
      </td>
    </tr>

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

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

<pre>
    Attempting to create an `llvm::StringLiteral` in C++23 mode currently causes an error. Specifically, the code we complain about is this constructor in `ADT/StringRef.h`:
```c++
    template <size_t N>
    constexpr StringLiteral(const char (&Str)[N])
#if defined(__clang__) && __has_attribute(enable_if)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wgcc-compat"
        __attribute((enable_if(__builtin_strlen(Str) == N - 1,
                               "invalid string literal")))
#pragma clang diagnostic pop
#endif
        : StringRef(Str, N - 1) {
    }
```
which can be reduced to (https://godbolt.org/z/xa3zs5qj6):
```c++
template <__SIZE_TYPE__ N>
constexpr void foo(const char (&Str)[N])
    __attribute((enable_if(__builtin_strlen(Str) == N - 1,
                            "invalid string literal")))
    {}

void x() {
    foo("1234");
}
```
which causes the following error:
```console
<source>:3:14: error: 'enable_if' attribute expression never produces a constant expression
    3 | __attribute((enable_if(__builtin_strlen(Str), ""))) {}
      |              ^
<source>:6:5: note: in instantiation of function template specialization 'foo<5UL>' requested here
    6 |     foo("1234");
      |     ^
<source>:3:41: note: read of variable 'Str' whose value is not known
    3 | __attribute((enable_if(__builtin_strlen(Str), ""))) {}
      |                                         ^
<source>:2:33: note: declared here
    2 | constexpr void foo(const char (&Str)[N])
      |        
```

The `enable_if` attribute has been there since 2016. Interestingly, we compile this just fine in C++20 mode, and Clang 20 doesn’t complain about it at all even in C++23 mode. 
</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJzEVt1u27gSfprxzSCGNLR-fOELxY6BAkVxcNKDg90bgZLGFrs06ZKU0-bpF5TsxEmaotgFdg0DEiSK8_0MZ0Z6r_aGeQXZLWSbmRxCb93qXjknVcezxnbfV1UIfDgGZfYYLLaOZWCUBiFPtD4dQFQgqvvglNl_VIGd1JAnqAyugW6BbkngwXaM7eAcm6C_YysHzz7uwc5ZN8f7I7dqp1qp9XegNYaesY3fPMTr4ailMigbOwRUHkOvPLbW-OCGNlgXY0GeVJvPQNsJyH95N-8hTyK4pIo347-dEEFSISJGWjqSAbH26pHrgJ9A3J3fjgH429HhS25Ujm-w7aVDoBIovw8OaAnZ7SfINvEuqYCE2mHHO2W4AyrrutXS7OsaaIlAOVCOdd1LX8sQnGqGwEAlG9lortXuaZOjk_uDxPFj7JTcG-uDavE4-P7nK9TeWMcdAtHN__dtexOFlAGIzgTjr34R_iWCsq6bQemgTO2D02yAyokpgtiA2OAnvMEUaH214Ts_IFLmJLXq0I9qor7ISZHr9P85Y3ucFrDp1O4qJIgKn1y_YFxfwC0RiovhUGyuswGS6qFXbY-tNNgwOu6GlruY5UBlH8LRx_yhLdB2b7vG6jC3bg-0fQTafpPi0Wdfv-QR-Xtpdp1idX3_4fe7-vNv_7mr60umPWfZyaoOd9b-YoL9Y-79qnWTwLdnjZNq5PNtxHXtwcQQiFISi_MWIr5835yxWMSSsLNa24cIYawbr1W3xlvN8ZFYezu4lqPGohIgqnQR0-TyGQIVV1oV-KQjRi_Ye2UNGj6xw6OzMS08yqkkSBOuFp1ZCYRi_Rf9iMk6CvEs57OQZw-K9StTsru3PHMQVRbZGRs4XpVBNSFWMkRGdoe7wbTj_VNq-lh8pVaP0xqgInok1tn_PsZ9qUDHXwf2gTvs2fEZVf6E6l1LX4L_IebozSK9Bu1YdhHoSToV1YuARqEKfOitZzxJPXDsA8YG_MPYh3_LhJ8dmh9xpchXXHPtuNXSvdSVxkB_qy68wPrqUEFSfe459stnXfLk6gD00mPDbOKJc4xemZaRkjSf4wcT2LGPo8DUp8_tWWmemvKXwQeMLe-6_Sdj-4_LpelwPdZ1SrCz7A3cEZQJLJfhTZ8PKANKrZFPbN6OE3OcdSvRLcVSzniVFhkVSZpSOutXTUnlosuzUnRN3rZFWSZNJ3JqF7yQBS9makUJZUmR5pRSRulcyEQmi1x2aSo6LgQsEj5IpedxwIk1f6a8H3iVLpZpWc60bFj7cWgiGhsViGrnrAlsujGF1kDkeH8pEs-PvnAb_M1YTuPTbDNzqxjkphn2HhaJVj7457BBBT1OZ6NskG3wLpYwtOY8gb1j4vsT0VslZ4PTq1fdToV-aOatPQBtxyFvutwcnY0MgLajIB5oe9bktKI_AwAA___cHQrm">