https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107065
--- Comment #3 from Jason Liam <jlame646 at gmail dot com> ---
(In reply to Jonathan Wakely from comment #1)
> Reduced to remove the library dependency:
>
> enum Cat { prvalue, lvalue, xvalue };
>
> template<typename T>
> struct value_category {
> // Or can be an integral or enum value
> static constexpr auto value = prvalue;
> };
>
> template<typename T>
> struct value_category<T&> {
> static constexpr auto value = lvalue;
> };
>
> template<typename T>
> struct value_category<T&&> {
> static constexpr auto value = xvalue;
> };
>
> // Double parens for ensuring we inspect an expression,
> // not an entity
> #define VALUE_CATEGORY(expr) value_category<decltype((expr))>::value
>
> constexpr bool global = true;
> static_assert( VALUE_CATEGORY(!(!global)) == prvalue, "GCC gets this right"
> );
>
> int main()
> {
> bool b = true;
> if ( VALUE_CATEGORY(!(!b)) != prvalue )
> throw 1;
> }
Here is another reduced demo: https://godbolt.org/z/hGhfrKrad
```
#include <iostream>
int main() {
bool b = true;
std::cout << std::is_same<decltype(!(!b)), bool>::value << "\n";
auto bb = (!(!b));
std::cout << std::is_same<decltype(bb), bool>::value << "\n";
}
```