https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100946
Bug ID: 100946 Summary: [concepts] nonsensical results of compound requirements in requires expressions Product: gcc Version: 11.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: gcc at nospam dot scs.stanford.edu Target Milestone: --- Created attachment 50958 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=50958&action=edit test case (public domain) g++ handles compound requirements in requires clauses in an inconsistent way, almost as if the compiler itself is using an uninitialized variable. I'm checking the behavior with the following simple program: #include <iostream> #include <concepts> #define CHECK(e,T) \ std::cout << "Is " << #e << " of type " << #T << "? " << requires { \ { e } -> std::same_as<T>; \ } << std::endl int main() { std::cout << std::boolalpha; int i = 0; CHECK(0, int); //CHECK(0, int&); CHECK(i, int); CHECK(i, int&); } The above program yields the following output: Is 0 of type int? true Is i of type int? true Is i of type int&? true This doesn't make sense, since i can't be both int and int&. But then if I change the program to add the line CHECK(0,int&);, I get the following: Is 0 of type int? true Is 0 of type int&? false Is i of type int? true Is i of type int&? false This is wrong according to the spec--i should be of type int&, because you are supposed to use the expression rules [like decltype((e))] rather than the variable rules [like decltype(e)] for compound requirements. But what's even worse is the inconsistency between the two programs--somehow just adding a different check changed the behavior. If I remove the checks against 0 altogether, I get the following, which is correct according to the language spec, and again inconsistent with the previous examples: Is i of type int? false Is i of type int&? true