https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90734

Jonathan Wakely <redi at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |rejects-valid
             Status|UNCONFIRMED                 |NEW
   Last reconfirmed|                            |2019-10-29
                 CC|                            |redi at gcc dot gnu.org
           See Also|                            |https://gcc.gnu.org/bugzill
                   |                            |a/show_bug.cgi?id=82507
             Blocks|                            |67491
     Ever confirmed|0                           |1

--- Comment #2 from Jonathan Wakely <redi at gcc dot gnu.org> ---
Bug 82507 is fixed on trunk, but this isn't.

Refreshed for C++2a syntax (https://godbolt.org/z/M6D5k8):

template <bool B>
inline constexpr bool bool_ = B;

#if defined(WORKAROUND)
template<class T, class U>
concept Same_impl = __is_same_as(T, U);
#else
template <class T, class U>
concept Same_impl = bool_<__is_same_as(T, U)>;
#endif

template<class T, class U>
concept Same = Same_impl<T, U> && Same_impl<U, T>;

template<class T>
concept Foo = Same<const T&, const T&>;

template<class T>
concept Bar = Foo<T> && Same<T, T>;

template<class T>
struct S1 {
    // overload set incorrectly is ambiguous (should resolve to second
overload)
    static constexpr bool f() requires Foo<T> { return false; }
    static constexpr bool f() requires Bar<T> { return true; }
};

template<class T>
struct S2 {
    // overload set incorrectly is not ambiguous (resolves to third overload)
    static constexpr bool f() requires Foo<T> { return false; }
    static constexpr bool f() requires Bar<T> { return false; }
    static constexpr bool f() requires bool_<true> && true { return true; }
};

template<class T>
concept can_f = requires { T::f(); };

int main() {
    static_assert(Foo<int>);
    static_assert(Bar<int>);

    static_assert(can_f<S1<int>>);  // Fails
    static_assert(S1<int>::f());    // Bogus error

    static_assert(!can_f<S2<int>>); // Fails
#ifndef WORKAROUND
    static_assert(S2<int>::f());    // Bogus non-error
#endif
}


<source>: In function 'int main()':
<source>:48:30: error: call of overloaded 'f()' is ambiguous
   48 |     static_assert(S2<int>::f());    // Bogus non-error
      |                              ^
<source>:31:27: note: candidate: 'static constexpr bool S2<T>::f() requires 
Foo<T> [with T = int]'
   31 |     static constexpr bool f() requires Foo<T> { return false; }
      |                           ^
<source>:32:27: note: candidate: 'static constexpr bool S2<T>::f() requires 
Bar<T> [with T = int]'
   32 |     static constexpr bool f() requires Bar<T> { return false; }
      |                           ^
<source>:33:27: note: candidate: 'static constexpr bool S2<T>::f() requires
(bool_<true>) && true [with T = int]'
   33 |     static constexpr bool f() requires bool_<true> && true { return
true; }
      |                           ^

Compiler returned: 1


Referenced Bugs:

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67491
[Bug 67491] [meta-bug] concepts issues

Reply via email to