https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82740
Bug ID: 82740 Summary: [concepts] requires clause evaluated early Product: gcc Version: 8.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: Casey at Carter dot net Target Milestone: --- Created attachment 42483 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=42483&action=edit Repro Trunk as of 20170825 miscompiles this program (https://wandbox.org/permlink/70zH8c8JMQZMDUas): template<class T> concept bool C = requires(const T& t) { t.foo(); }; template<class T> struct Base { constexpr T const& derived() const { return static_cast<T const&>(*this); } constexpr bool bar() const requires #ifndef WORKAROUND requires(const T& t) { t.foo(); } #else C<T> #endif { derived().foo(); return true; } }; template<class T> struct Derived : Base<Derived<T>> { constexpr void foo() const {} }; int main() { static_assert(Derived<int>{}.bar()); } with diagnostics: prog.cc: In instantiation of 'struct Base<Derived<int> >': prog.cc:17:8: required from 'struct Derived<int>' prog.cc:22:32: required from here prog.cc:9:34: error: invalid use of incomplete type 'const struct Derived<int>' requires(const T& t) { t.foo(); } ~~^~~ prog.cc:17:8: note: declaration of 'struct Derived<int>' struct Derived : Base<Derived<T>> { ^~~~~~~ despite that N4700 [temp.inst]/16 (http://eel.is/c++draft/temp.spec#temp.inst-16) specifies that: The partial-concept-ids and requires-clause of a template specialization or member function are not instantiated along with the specialization or function itself, even for a member function of a local class; substitution into the atomic constraints formed from them is instead performed as specified in [temp.constr.decl] and [temp.constr.atomic] when determining whether the constraints are satisfied. [ Note: The satisfaction of constraints is determined during name lookup or overload resolution ([over.match]). — end note ] (Note that the text of [temp.inst]/16 in the Concepts TS is similar.) If WORKAROUND is defined, replacing the ad hoc requirement with an identical named concept, the program compiles without diagnostics.