[Bug c++/101113] g++ thinks constructor suppressed by a requires clause is actually a bad copy constructor
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101113 David Mazières changed: What|Removed |Added Status|NEW |RESOLVED Resolution|--- |INVALID --- Comment #4 from David Mazières --- Sorry I should have closed this bug report a while ago when I said it wasn't a bug.
[Bug c++/112715] Incorrect handling of template type aliases instantiated from decltype of lambdas
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112715 --- Comment #1 from David Mazières --- I should have mentioned, I hereby place the test case in the public domain.
[Bug c++/112715] New: Incorrect handling of template type aliases instantiated from decltype of lambdas
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112715 Bug ID: 112715 Summary: Incorrect handling of template type aliases instantiated from decltype of lambdas Product: gcc Version: 13.2.1 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 56689 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=56689=edit File that should compile but doesn't I'm using g++ version 13.2.1 on arch linux, configured as follows: $ g++ -v Using built-in specs. COLLECT_GCC=g++ COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-pc-linux-gnu/13.2.1/lto-wrapper Target: x86_64-pc-linux-gnu Configured with: /build/gcc/src/gcc/configure --enable-languages=ada,c,c++,d,fortran,go,lto,objc,obj-c++ --enable-bootstrap --prefix=/usr --libdir=/usr/lib --libexecdir=/usr/lib --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=https://bugs.archlinux.org/ --with-build-config=bootstrap-lto --with-linker-hash-style=gnu --with-system-zlib --enable-__cxa_atexit --enable-cet=auto --enable-checking=release --enable-clocale=gnu --enable-default-pie --enable-default-ssp --enable-gnu-indirect-function --enable-gnu-unique-object --enable-libstdcxx-backtrace --enable-link-serialization=1 --enable-linker-build-id --enable-lto --enable-multilib --enable-plugin --enable-shared --enable-threads=posix --disable-libssp --disable-libstdcxx-pch --disable-werror Thread model: posix Supported LTO compression algorithms: zlib zstd gcc version 13.2.1 20230801 (GCC) When defining template type aliases, I get bizarrely incorrect types in some contexts but not others. For example, the static assertion fails in this code but should not: #include template using uintsz = decltype([](auto i){ if constexpr (i <= 32) return 0; else return 0L; }(std::integral_constant{})); template constexpr uintsz<8*Nbytes> f() { return 0; } static_assert(std::is_same_v()), uintsz<56>>); Specifically I get the following error: $ g++ -std=c++20 -ggdb -O -Wall -c -o uintsz.o uintsz.cc uintsz.cc:18:20: error: static assertion failed 18 | static_assert(std::is_same_v()), uintsz<56>>); | ~^~~ This feels like some sort of state corruption in the compiler, because there are more complicated examples in which gcc rejects other things inside functions (like rejecting a using type alias and accepting the corresponding typedef). I think this example suffices to show the problem, but I could try to reduce another test case if necessary. In all cases, clang++ -std=c++20 accepts the code.
[Bug c++/107889] New: Incorrect parsing of qualified friend function returning decltype(auto)
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107889 Bug ID: 107889 Summary: Incorrect parsing of qualified friend function returning decltype(auto) Product: gcc Version: 12.2.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: --- G++ 12.2.0 rejects a valid friend declaration for a fully-qualified function returning `decltype(auto)`. To reproduce the problem, you can try to compile the following code with `g++ -std=c++20 -c bug.cc`: decltype(auto) f() { } struct S { friend decltype(auto) ::f(); }; This results in the following error: $ c++ -std=c++20 -c bug.cc bug.cc:7:27: error: 'decltype(auto)' is not a class type 7 | friend decltype(auto) ::f(); | ^ bug.cc:7:27: error: 'decltype(auto)' is not a class type bug.cc:7:27: error: 'decltype(auto)' is not a class type bug.cc:7:29: error: 'decltype(auto)' is not a class type 7 | friend decltype(auto) ::f(); | ^ bug.cc:7:10: error: ISO C++ forbids declaration of 'f' with no type [-fpermissive] 7 | friend decltype(auto) ::f(); | ^~ bug.cc:7:29: error: invalid use of 'decltype(auto)' 7 | friend decltype(auto) ::f(); A similar problem was reported in bug #59766 for friend functions returning auto. It seems to have been mostly fixed, but the combination of decltype(auto) and the function name being qualified (::f) is still a problem.
[Bug c++/101113] g++ thinks constructor suppressed by a requires clause is actually a bad copy constructor
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101113 --- Comment #3 from David Mazieres --- (In reply to TC from comment #2) > https://eel.is/c++draft/class.copy.ctor#5 > > I don't think this code is valid. The constraint (which isn't checked until > overload resolution time anyway) can't suppress the outright ill-formedness > of the declaration. Admittedly, 11.4.5.3/5 makes no mention of constraints: A declaration of a constructor for a class X is ill-formed if its first parameter is of type cv X and either there are no other parameters or else all other parameters have default arguments. A member function template is never instantiated to produce such a constructor signature. - https://timsong-cpp.github.io/cppwp/n4868/class.copy.ctor#5 On the other hand, suppressed functions should not participate in overload resolution. Here's some normative language to the same effect 12.4.3/3: Second, for a function to be viable, if it has associated constraints ([temp.constr.decl]), those constraints shall be satisfied ([temp.constr.constr]). - https://timsong-cpp.github.io/cppwp/n4868/over.match.viable#3 So here's another example that doesn't involve 11.4.5.3/5: #include template struct S2 { static T *fn() requires (!std::is_reference_v) { return nullptr; } static std::nullptr_t fn() requires std::is_reference_v { return {}; } }; void f() { auto p = S2::fn(); } $ g++ -std=c++20-c -o constructor.o constructor.cc constructor.cc: In instantiation of 'struct S2': constructor.cc:11:20: required from here constructor.cc:4:13: error: forming pointer to reference type 'int&' 4 | static T *fn() requires (!std::is_reference_v) { return nullptr; } | ^~ make: *** [: constructor.o] Error 1 So I guess your argument is that there's a certain level of well-formedness required even before the constraints can be evaluated, and an X::X(X) method is as non-sensical as a type like "int&*". That seems like a reasonable position, though I wish the standard were more explicit. I apologize for wasting your time if this was a bogus bug report. For the record, in case the closed bug report comes up in anyone's web search, an easy fix is to rely on the fact that templates won't be instantiated to bad copy constructors: template struct S { S() {} template S(S) requires B2 {} }; S sf; S st;
[Bug c++/101113] New: g++ thinks constructor suppressed by a requires clause is actually a bad copy constructor
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101113 Bug ID: 101113 Summary: g++ thinks constructor suppressed by a requires clause is actually a bad copy constructor 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: --- g++ 11.1.0 is rejecting the following correct code when compiling with `-std=c++20` (test case public domain): template struct S { S() {} S(S) requires B {} }; S sf; Here is the error message: $ g++ -std=c++20 -c test.cc y.cc: In instantiation of 'struct S': y.cc:3:26: required from here y.cc:3:3: error: invalid constructor; you probably meant 'S (const S&)' 3 | S(S) requires B {} | ^
[Bug c++/100946] New: [concepts] nonsensical results of compound requirements in requires expressions
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=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 #include #define CHECK(e,T) \ std::cout << "Is " << #e << " of type " << #T << "? " << requires { \ { e } -> std::same_as; \ } << 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