From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from us-smtp-delivery-1.mimecast.com (us-smtp-1.mimecast.com [207.211.31.81]) by sourceware.org (Postfix) with ESMTP id 2480D385DC0A for ; Sat, 4 Apr 2020 23:31:33 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 2480D385DC0A Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-481-6V416TKpMaq1nmTwBAMMkw-1; Sat, 04 Apr 2020 19:31:29 -0400 X-MC-Unique: 6V416TKpMaq1nmTwBAMMkw-1 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id EC7968017CE for ; Sat, 4 Apr 2020 23:31:27 +0000 (UTC) Received: from pdp-11.redhat.com (ovpn-112-138.rdu2.redhat.com [10.10.112.138]) by smtp.corp.redhat.com (Postfix) with ESMTP id 610CB60BFB; Sat, 4 Apr 2020 23:31:27 +0000 (UTC) From: Marek Polacek To: Jason Merrill , GCC Patches Subject: [PATCH] c++: C++20 DR 2237, disallow simple-template-id in cdtor. Date: Sat, 4 Apr 2020 19:30:53 -0400 Message-Id: <20200404233053.1073028-1-polacek@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable X-Spam-Status: No, score=-30.5 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 04 Apr 2020 23:31:35 -0000 This patch implements DR 2237 which says that a simple-template-id is no longer valid as the declarator-id of a constructor or destructor; see . It is not explicitly stated but out-of-line destructors with a simple-template-id are also meant to be ill-formed now. (Out-of-line constructors like that are invalid since DR1435 I think.) This change only applies to C++20; it is not a DR against C++17. I'm not crazy about the diagnostic in constructors but ISTM that cp_parser_constructor_declarator_p shouldn't print errors. Does it seem reasonable to apply this now or should I defer to GCC 11? Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk? 2020-04-04 Marek Polacek =09DR 2237 =09* parser.c (cp_parser_unqualified_id): Reject simple-template-id as =09the declarator-id of a destructor. =09(cp_parser_constructor_declarator_p): Reject simple-template-id as =09the declarator-id of a constructor. =09* g++.dg/DRs/dr2237.C: New test. =09* g++.dg/parse/constructor2.C: Add dg-error for C++20. =09* g++.dg/parse/dtor12.C: Likewise. =09* g++.dg/parse/dtor4.C: Likewise. =09* g++.dg/template/dtor4.C: Adjust dg-error. =09* g++.dg/template/error34.C: Likewise. =09* g++.old-deja/g++.other/inline15.C: Only run for C++17 and lesses. =09* g++.old-deja/g++.pt/ctor2.C: Add dg-error for C++20. --- gcc/cp/parser.c | 16 ++++++++++++++++ gcc/testsuite/g++.dg/DRs/dr2237.C | 18 ++++++++++++++++++ gcc/testsuite/g++.dg/parse/constructor2.C | 4 ++-- gcc/testsuite/g++.dg/parse/dtor12.C | 2 +- gcc/testsuite/g++.dg/parse/dtor4.C | 2 +- gcc/testsuite/g++.dg/template/dtor4.C | 2 +- gcc/testsuite/g++.dg/template/error34.C | 10 +++++----- .../g++.old-deja/g++.other/inline15.C | 2 +- gcc/testsuite/g++.old-deja/g++.pt/ctor2.C | 2 +- 9 files changed, 46 insertions(+), 12 deletions(-) create mode 100644 gcc/testsuite/g++.dg/DRs/dr2237.C diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 7e5921e039f..810edfa87a9 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -6114,6 +6114,16 @@ cp_parser_unqualified_id (cp_parser* parser, =09 return build_min_nt_loc (loc, BIT_NOT_EXPR, make_auto ()); =09 } =20 +=09/* DR 2237 (C++20 only): A simple-template-id is no longer valid as the +=09 declarator-id of a constructor or destructor. */ +=09if (token->type =3D=3D CPP_TEMPLATE_ID && cxx_dialect >=3D cxx2a) +=09 { +=09 if (!cp_parser_uncommitted_to_tentative_parse_p (parser)) +=09 error_at (tilde_loc, "template-id not allowed for destructor"); +=09 cp_parser_simulate_error (parser); +=09 return error_mark_node; +=09 } + =09/* If there was an explicit qualification (S::~T), first look =09 in the scope given by the qualification (i.e., S). =20 @@ -28675,6 +28685,12 @@ cp_parser_constructor_declarator_p (cp_parser *par= ser, cp_parser_flags flags, if (!constructor_name_p (id, nested_name_specifier)) =09constructor_p =3D false; } + /* DR 2237 (C++20 only): A simple-template-id is no longer valid as the + declarator-id of a constructor or destructor. */ + else if (constructor_p +=09 && cxx_dialect >=3D cxx2a +=09 && cp_lexer_next_token_is (parser->lexer, CPP_TEMPLATE_ID)) + constructor_p =3D false; /* If we still think that this might be a constructor-declarator, look for a class-name. */ else if (constructor_p) diff --git a/gcc/testsuite/g++.dg/DRs/dr2237.C b/gcc/testsuite/g++.dg/DRs/d= r2237.C new file mode 100644 index 00000000000..17abdf179c1 --- /dev/null +++ b/gcc/testsuite/g++.dg/DRs/dr2237.C @@ -0,0 +1,18 @@ +// DR 2237 - Can a template-id name a constructor? + +template +struct X { + X(); // { dg-error "expected" "" { target c++2a } } + X(int); // OK, injected-class-name used + ~X(); // { dg-error "template-id not allowed for destructor" "" { tar= get c++2a } } +}; + +// ill-formed since DR1435 +template X::X() {} // { dg-error "names the constructor|= as no template constructors" } +template X::~X() {} // { dg-error "template-id not allow= ed for destructor" "" { target c++2a } } + +struct Q { + // ill-formed since DR1435 + template friend X::X(); // { dg-error "names the const= ructor|as no template constructors" } + template friend X::~X(); // { dg-error "template-id no= t allowed for destructor" "" { target c++2a } } +}; diff --git a/gcc/testsuite/g++.dg/parse/constructor2.C b/gcc/testsuite/g++.= dg/parse/constructor2.C index e514e9397e9..87007e9c715 100644 --- a/gcc/testsuite/g++.dg/parse/constructor2.C +++ b/gcc/testsuite/g++.dg/parse/constructor2.C @@ -5,7 +5,7 @@ class T {=20 public:=20 T(short,short f=3D0) {}=20 - T(int f) {}=20 - T(int f=3D0,const char* b=3D0) {}=20 + T(int f) {} // { dg-error "expected" "" { target c++2a } } + T(int f=3D0,const char* b=3D0) {} // { dg-error "expected" "" { = target c++2a } } };=20 =20 diff --git a/gcc/testsuite/g++.dg/parse/dtor12.C b/gcc/testsuite/g++.dg/par= se/dtor12.C index 1acdfa36b69..d758d3e861d 100644 --- a/gcc/testsuite/g++.dg/parse/dtor12.C +++ b/gcc/testsuite/g++.dg/parse/dtor12.C @@ -2,5 +2,5 @@ =20 template class a { - ~a(); + ~a(); // { dg-error "template-id not allowed for destructor" "" { tar= get c++2a } } }; diff --git a/gcc/testsuite/g++.dg/parse/dtor4.C b/gcc/testsuite/g++.dg/pars= e/dtor4.C index 729ee2fa130..1059c189eff 100644 --- a/gcc/testsuite/g++.dg/parse/dtor4.C +++ b/gcc/testsuite/g++.dg/parse/dtor4.C @@ -7,4 +7,4 @@ template struct X { }; =20 template -X::~X(){} +X::~X(){} // { dg-error "template-id not allowed for destructor" "" = { target c++2a } } diff --git a/gcc/testsuite/g++.dg/template/dtor4.C b/gcc/testsuite/g++.dg/t= emplate/dtor4.C index 4f277b248bd..917681fc13e 100644 --- a/gcc/testsuite/g++.dg/template/dtor4.C +++ b/gcc/testsuite/g++.dg/template/dtor4.C @@ -5,5 +5,5 @@ =20 template struct A { - ~A<0>(); // { dg-error "parse error|declaration" } + ~A<0>(); // { dg-error "parse error|declaration|template-id" } }; diff --git a/gcc/testsuite/g++.dg/template/error34.C b/gcc/testsuite/g++.dg= /template/error34.C index d0cbcaef28e..ab688d9ba8c 100644 --- a/gcc/testsuite/g++.dg/template/error34.C +++ b/gcc/testsuite/g++.dg/template/error34.C @@ -3,27 +3,27 @@ =20 template struct A { - A<__builtin_offsetof(T, x)>();=09// { dg-error "type/value mismatch|offs= etof\\(T, x\\)" } + A<__builtin_offsetof(T, x)>();=09// { dg-error "type/value mismatch|offs= etof\\(T, x\\)|expected" } }; =20 template struct B { - B<__builtin_offsetof(T, x.y)>();=09// { dg-error "type/value mismatch|of= fsetof\\(T, x.y\\)" } + B<__builtin_offsetof(T, x.y)>();=09// { dg-error "type/value mismatch|of= fsetof\\(T, x.y\\)|expected" } }; =20 template struct C { - C<__builtin_offsetof(T, x[6])>();=09// { dg-error "type/value mismatch|o= ffsetof\\(T, x\\\[6\\\]\\)" } + C<__builtin_offsetof(T, x[6])>();=09// { dg-error "type/value mismatch|o= ffsetof\\(T, x\\\[6\\\]\\)|expected" } }; =20 template struct D { - D<__builtin_offsetof(T, x.y[6].z)>();=09// { dg-error "type/value mismat= ch|offsetof\\(T, x.y\\\[6\\\].z\\)" } + D<__builtin_offsetof(T, x.y[6].z)>();=09// { dg-error "type/value mismat= ch|offsetof\\(T, x.y\\\[6\\\].z\\)|expected" } }; =20 struct E { int x; }; =20 template struct F { - F<__builtin_offsetof(E, x)>();=09// { dg-error "type/value mismatch|offs= etof\\(E, x\\)" } + F<__builtin_offsetof(E, x)>();=09// { dg-error "type/value mismatch|offs= etof\\(E, x\\)|expected" } }; diff --git a/gcc/testsuite/g++.old-deja/g++.other/inline15.C b/gcc/testsuit= e/g++.old-deja/g++.other/inline15.C index 43f7f5e3025..a31c60960a5 100644 --- a/gcc/testsuite/g++.old-deja/g++.other/inline15.C +++ b/gcc/testsuite/g++.old-deja/g++.other/inline15.C @@ -1,4 +1,4 @@ -// { dg-do assemble } +// { dg-do assemble { target c++17_down } } // { dg-options "-O1" } // Origin: Jakub Jelinek =20 diff --git a/gcc/testsuite/g++.old-deja/g++.pt/ctor2.C b/gcc/testsuite/g++.= old-deja/g++.pt/ctor2.C index a8be91ddbb9..4159c84ff56 100644 --- a/gcc/testsuite/g++.old-deja/g++.pt/ctor2.C +++ b/gcc/testsuite/g++.old-deja/g++.pt/ctor2.C @@ -4,7 +4,7 @@ =20 template struct A { - A(); + A(); // { dg-error "expected" "" { target c++2a } } }; =20 template base-commit: 49a86fce1a879a206fb4b27f097910005d968fda --=20 Marek Polacek =E2=80=A2 Red Hat, Inc. =E2=80=A2 300 A St, Boston, MA