https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97988
Bug ID: 97988 Summary: [C++20] Forward-declared class type declared inside requires-expression gives weird inconsistencies Product: gcc Version: 11.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: arthur.j.odwyer at gmail dot com Target Milestone: --- // https://godbolt.org/z/sxWY1f template<class P> concept C = requires (P ptr) { (struct D*)ptr; }; struct D {}; D d; ==== Clang accepts. GCC rejects; GCC's error messages imply that GCC is sometimes treating `D` as a class template `template<class P> struct D` and sometimes treating it as a normal class type, as if its internal representation is inconsistent. <source>:6:3: error: class template argument deduction failed: 6 | D d; | ^ <source>:6:3: error: no matching function for call to 'D()' <source>:3:40: note: candidate: 'template<class P> D()-> D' 3 | concept C = requires (P ptr) { (struct D*)ptr; }; | ^ <source>:3:40: note: template argument deduction/substitution failed: <source>:6:3: note: couldn't deduce template parameter 'P' 6 | D d; | ^ <source>:3:40: note: candidate: 'template<class P> D(D)-> D' 3 | concept C = requires (P ptr) { (struct D*)ptr; }; | ^ <source>:3:40: note: template argument deduction/substitution failed: <source>:6:3: note: candidate expects 1 argument, 0 provided 6 | D d; | ^ ==== I can also make GCC segfault by trying to use `D` as an NTTP, but I think that's essentially just a duplicate of #95159 #95291 #96123 #97749 etc., not necessarily related to the rejects-invalid bug described here. template<class P> concept C = requires (P ptr) { (struct D*)ptr; }; struct D { constexpr D(); }; template<D d> struct S {}; S<1> s;