Hi, GCC 11 rejects the following code when the class 'A' is instantiated. When I fed it into GCC 1O, it is accepted. Also, clang accepts it. I guess maybe it is valid. $ cat s.cpp template <class T> class A { public: A(short,short a=0) {} A<T>(short b) {} }; $ g++ -c s.cpp s.cpp:4:10: error: expected unqualified-id before ‘short’ 4 | A<T>(short b) {} | ^~~~~ s.cpp:4:10: error: expected ‘)’ before ‘short’ 4 | A<T>(short b) {} | ~^~~~~ | ) $ g++ -v Using built-in specs. COLLECT_GCC=/usr/local/gcc-20200920/bin/g++ COLLECT_LTO_WRAPPER=/usr/local/gcc-20200920/libexec/gcc/x86_64-pc-linux-gnu/11.0.0/lto-wrapper Target: x86_64-pc-linux-gnu Configured with: ../gcc-11-20200920/configure --prefix=/usr/local/gcc-20200920 --enable-checking=release --enable-languages=c,c++ --disable-multilib Thread model: posix Supported LTO compression algorithms: zlib gcc version 11.0.0 20200920 (experimental) (GCC)
Could this be a c++17 difference?
This is C++20 DR 2237, disallow simple-template-id in cdtor: see [diff.cpp17.class]p2. Just the diagnostic we give is horrible ;(. Remove <T> to make this work.
Actually, let me reopen this to improve the diagnostic.
*** Bug 100997 has been marked as a duplicate of this bug. ***
*** Bug 101032 has been marked as a duplicate of this bug. ***
If the invalid special member is defined out of the class body, you get another error: template<typename T> struct F { F<T>(); }; template<typename T> inline F<T>::F() { } 101032.C:4:8: error: expected unqualified-id before ‘)’ token 4 | F<T>(); | ^ 101032.C:8:8: error: no declaration matches ‘F<T>::F()’ 8 | inline F<T>::F() { } | ^~~~ 101032.C:8:8: note: no functions named ‘F<T>::F()’ 101032.C:2:8: note: ‘struct F<T>’ defined here 2 | struct F | ^ As well as improving the first error (which is the subject of this bug) maybe the constructor could be parsed as though it had been written correctly, so that the "no declaration matches" error doesn't happen. Compilation is already going to fail, we don't need to also complain about the valid function definition not matching anything.
*** Bug 104437 has been marked as a duplicate of this bug. ***
PR 104437 pointed out that the invalid constructor is accepted if it has a redundant inline specifier: template<typename Base> struct S : Base { inline S<Base>() {} };
The trunk branch has been updated by Marek Polacek <mpolacek@gcc.gnu.org>: https://gcc.gnu.org/g:cff174fabd6c980c09aee95db1d9d5c22421761f commit r14-8915-gcff174fabd6c980c09aee95db1d9d5c22421761f Author: Marek Polacek <polacek@redhat.com> Date: Fri Feb 2 14:53:01 2024 -0500 c++: DR2237, cdtor and template-id tweaks [PR107126] Since my r11-532 changes to implement DR2237, for this test: template<typename T> struct S { S<T>(); }; in C++20 we emit the ugly: q.C:3:8: error: expected unqualified-id before ')' token 3 | S<T>(); which doesn't explain what the problem is. This patch improves that diagnostic, reduces the error to a pedwarn, and adds a -Wc++20-compat diagnostic. We now say: q.C:3:7: warning: template-id not allowed for constructor in C++20 [-Wtemplate-id-cdtor] 3 | S<T>(); q.C:3:7: note: remove the '< >' This patch also fixes <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97202#c8> where the C++20 diagnostic was missing altogether: The problem was that I checked for CPP_TEMPLATE_ID too early, at a point at which cp_parser_template_id may not have been called yet. So let's check for it at the end of the function, after the tentative parse and rollback. -Wc++20-compat triggered in libitm/; I sent a patch for that. DR 2237 PR c++/107126 PR c++/97202 gcc/c-family/ChangeLog: * c-opts.cc (c_common_post_options): In C++20 or with -Wc++20-compat, turn on -Wtemplate-id-cdtor. * c.opt (Wtemplate-id-cdtor): New. gcc/cp/ChangeLog: * parser.cc (cp_parser_unqualified_id): Downgrade the DR2237 error to a pedwarn. (cp_parser_constructor_declarator_p): Likewise. gcc/ChangeLog: * doc/invoke.texi: Document -Wtemplate-id-cdtor. gcc/testsuite/ChangeLog: * g++.dg/DRs/dr2237.C: Adjust dg-error. * g++.dg/parse/constructor2.C: Likewise. * g++.dg/template/error34.C: Likewise. * g++.old-deja/g++.pt/ctor2.C: Likewise. * g++.dg/DRs/dr2237-2.C: New test. * g++.dg/DRs/dr2237-3.C: New test. * g++.dg/DRs/dr2237-4.C: New test. * g++.dg/DRs/dr2237-5.C: New test. * g++.dg/warn/Wtemplate-id-cdtor-1.C: New test. * g++.dg/warn/Wtemplate-id-cdtor-2.C: New test. * g++.dg/warn/Wtemplate-id-cdtor-3.C: New test. * g++.dg/warn/Wtemplate-id-cdtor-4.C: New test.
Should be all fixed now.