Bug 112749 - GCC accepts invalid code in concepts (requires clause incorrectly satisfied)
Summary: GCC accepts invalid code in concepts (requires clause incorrectly satisfied)
Status: RESOLVED DUPLICATE of bug 102419
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 13.2.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2023-11-28 18:22 UTC by Caleb Sunstrum
Modified: 2023-11-28 20:44 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Caleb Sunstrum 2023-11-28 18:22:08 UTC
The below example is ill-formed - the requires clause should not be satisfied due to the failure to instantiate W1<int>, but GCC accepts the code nonetheless.

Clang rejects the code.

$ cat gcc-bug.cpp
template<class> concept C1 = true;

template<class T> using W1 = decltype(nonexistent<T>(0));

template<class T>
requires C1<W1<T>>
void func(T);

void test() {
  func(0);
}

$ g++ -c -std=c++20 gcc-bug.cpp

$ clang++ -c -std=c++20 gcc-bug.cpp
gcc-bug.cpp:10:3: error: no matching function for call to 'func'
   10 |   func(0);
      |   ^~~~
gcc-bug.cpp:7:6: note: candidate template ignored: constraints not satisfied [with T = int]
    7 | void func(T);
      |      ^
gcc-bug.cpp:3:39: note: because substituted constraint expression is ill-formed: use of undeclared identifier 'nonexistent'
    3 | template<class T> using W1 = decltype(nonexistent<T>(0));
      |                                       ^
1 error generated.
Comment 1 Patrick Palka 2023-11-28 20:44:27 UTC
Thanks for the bug report, I think this is pretty much a dup of PR102419.

GCC is behaving correctly here: the normal form of the constraint C1<W1<T>> is just 'true (with empty parameter mapping)' which is independent of the template parameter, so the constraint is trivially satisfied for any choice of T.  To get the behavior you desire, define C1 in a way that depends on its template parameter e.g.

template<class T> concept C1 = requires { typename T; };

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