Bug 97988 - [C++20] Forward-declared class type declared inside requires-expression gives weird inconsistencies
Summary: [C++20] Forward-declared class type declared inside requires-expression gives...
Status: RESOLVED DUPLICATE of bug 101677
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 11.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: ice-on-invalid-code, rejects-valid
Depends on:
Blocks: c++-lookup, c++-name-lookup
  Show dependency treegraph
 
Reported: 2020-11-25 16:20 UTC by Arthur O'Dwyer
Modified: 2023-06-09 14:36 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2021-08-17 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Arthur O'Dwyer 2020-11-25 16:20:58 UTC
// 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;
Comment 1 Andrew Pinski 2021-08-17 08:36:10 UTC
It seems like it is creating a struct D with the template argument in the global namespace.
If I add struct D; at the very begining of the file, it all works.
Comment 2 Patrick Palka 2023-06-09 14:36:01 UTC
Seems to be fixed by r12-7997, so I suppose let's call this as dup of PR101677.

*** This bug has been marked as a duplicate of bug 101677 ***