From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from NAM02-SN1-obe.outbound.protection.outlook.com (mail-sn1anam02olkn2052.outbound.protection.outlook.com [40.92.44.52]) by sourceware.org (Postfix) with ESMTPS id CA9473858402 for ; Fri, 24 Sep 2021 11:14:09 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org CA9473858402 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=Kje2kuUeVQlyvJwa+gKgZ2OpEsdW1JzEqBz5A7y6i226AAen4Bdrvu1TgxVA7xgPcWbcxu/wVFUHY7k8ujVOO9wm9yqN+xVjYOswSDS4xntz1tEKVdsuJbeZSo7jIP0DuOZr1ZB+Jhrr7jZVcrAiKnJEEiMARXu0BnQz9x2X9vFdXeTKp1H7I0K5950OdUdrR7+/uiqw92/KNIqNEoRLTb/j3P5MDZvzYKV7yrF4434ngbeENQIaPUppBrprxB2alcKhy+RSOnAwG+9PgyZTz78Vn9sv+4TgxIybxiZOFWblxBSFFoVc4Y3FNLcCvjKejFPaceC5q6YXgo8yUAbO7Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=VpeQ3KWNDQqq7o7Roz1lPhxalt69HFO6l1MfOX3VCHA=; b=CKx1tIkFs+BBYtjTCZ45a1bb7BASrBHnWm8S0WYSJ5VRXK9UKECza8v0NX/YKBSKvuCPxGonK7wH7nurx3v1FGQo1CH7dQ88Bdz1mYsstp2JZ1m0K3qNvsTZ+VlTA45V3gyy5EEAWs/pFjH8brSr1MFocRcP6SRIqdOHC342RWSxHSfiaY8r7+X8I/M6cZYl2keeoiUDvTuKtpXA2TAxsDzearDGubjMSIcMbUN70YAFKROKnIu2+4JvpQVnE1eVe/h1v5ovAGOsGur+sinQh/pTRirBHLyET1r+CMgZoSFMy+97wRshSyBHgI8WMBjv0+V2HMqRYDy1owZdnsUc6g== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=none; dmarc=none; dkim=none; arc=none Received: from DM5PR0501MB3733.namprd05.prod.outlook.com (2603:10b6:4:80::23) by DM5PR05MB2971.namprd05.prod.outlook.com (2603:10b6:3:55::18) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4566.9; Fri, 24 Sep 2021 11:14:08 +0000 Received: from DM5PR0501MB3733.namprd05.prod.outlook.com ([fe80::80fb:3d56:dd10:755d]) by DM5PR0501MB3733.namprd05.prod.outlook.com ([fe80::80fb:3d56:dd10:755d%7]) with mapi id 15.20.4544.018; Fri, 24 Sep 2021 11:14:07 +0000 From: nick huang To: "gcc-patches@gcc.gnu.org" Subject: *PING* [PATCH] c++: fix cases of core1001/1322 by not dropping cv-qualifier of function parameter of type of typename or decltype[PR101402,PR102033,PR102034,PR102039,PR102044] Thread-Topic: *PING* [PATCH] c++: fix cases of core1001/1322 by not dropping cv-qualifier of function parameter of type of typename or decltype[PR101402,PR102033,PR102034,PR102039,PR102044] Thread-Index: AQHXnm3npvcE3z86VU61Xh5HS2CgaKuzLUUn Date: Fri, 24 Sep 2021 11:14:07 +0000 Message-ID: References: In-Reply-To: Accept-Language: en-CA, en-US Content-Language: en-CA X-MS-Has-Attach: X-MS-TNEF-Correlator: suggested_attachment_session_id: c06fe9ef-b936-e250-10b9-31631045d5a1 x-ms-exchange-messagesentrepresentingtype: 1 x-tmn: [nqgaCkt9tbywE6GkRALolZ9Z2Gd9K6v+] x-ms-publictraffictype: Email x-ms-office365-filtering-correlation-id: 02ff69d1-2fd1-4ba3-5e9f-08d97f4c6d63 x-ms-traffictypediagnostic: DM5PR05MB2971: x-microsoft-antispam: BCL:0; x-microsoft-antispam-message-info: KKrF8yrMDD3bwmIzyi455LqC4CW1t9KKkAVcNHgXalgL7o9XOKhkyif4H1GYt5xh+e+G6FQ23A0iJE1/h1maGO/n1FmxPQ2XkZfDIp3F2x8XDXC7e8KQYsB/UN4YHNPpmyK7rED1hJj/UcXs/ViceFMnWAUTHyp3VetVmyXTSFsAoTf5I2u0tjMTGXRHpJygAIcLvUYTdbr7Hd9qUzijHV6rFc2tvV5lmjov9OzePKUry7PkbT7fiRhPdnH4yY3zXhkV9yJPQmLS/Ilr8ejsoIZcH6Yrl5XeA9bdZYiy7IMgVevvh2904o8r3Rx5M4n9SlDqWGS6Pc5VY8pSYEdag8q6u+/PZQrItodCMk93Kj3Bsd12+l2VqsKZY9+jrgociHa6uzZEun/kLmERMyU3/ut4WpTcUo1+co5itgiC2GCcXoWlI77wiU96G09PI0Z9lWyw1Q7AZ0i3Tww+ubC6uZRem9lMSQngA5AnQnd1kmI= x-ms-exchange-antispam-messagedata-chunkcount: 1 x-ms-exchange-antispam-messagedata-0: Ff4Kt06DQLBTaeswGX5X6v+9rOcoNN/qJYUUR7qt3G4W73JMLZ9fp9zS/BCJlLGoGuSNAzX/L4yMiEg6HODpe8qzLpNGu1i1RAU7hQUf5FKfHpywW5OwaOIajPZdIWXyuHkN5Cv/nPOzlz0MkJ6NFQ== x-ms-exchange-transport-forked: True Content-Type: text/plain; charset="Windows-1252" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 X-OriginatorOrg: sct-15-20-3174-8-msonline-outlook-e6bda.templateTenant X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-AuthSource: DM5PR0501MB3733.namprd05.prod.outlook.com X-MS-Exchange-CrossTenant-RMS-PersistedConsumerOrg: 00000000-0000-0000-0000-000000000000 X-MS-Exchange-CrossTenant-Network-Message-Id: 02ff69d1-2fd1-4ba3-5e9f-08d97f4c6d63 X-MS-Exchange-CrossTenant-originalarrivaltime: 24 Sep 2021 11:14:07.8706 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 84df9e7f-e9f6-40af-b435-aaaaaaaaaaaa X-MS-Exchange-CrossTenant-rms-persistedconsumerorg: 00000000-0000-0000-0000-000000000000 X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM5PR05MB2971 X-Spam-Status: No, score=-9.0 required=5.0 tests=BAYES_00, BODY_8BITS, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_ENVFROM_END_DIGIT, FREEMAIL_FROM, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2, SPF_HELO_PASS, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) 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: Fri, 24 Sep 2021 11:14:12 -0000 These bugs are considered duplicate cases of PR51851 which has been suspend= ed =0A= since 2012, an issue known as "core1001/1322". Considering this background,= =0A= it deserves a long comment to explain.=0A= =0A= Many people believed the root cause of this family of bugs is related with = =0A= the nature of how and when the array type is converted to pointer type duri= ng =0A= function signature is calculated. This is true, but we may need to go into = details =0A= to understand the exact reason.=0A= =0A= There is a pattern for these bugs(PR101402,PR102033,PR102034,PR102039). In = the =0A= template function declaration, the function parameter is consisted of a "co= nst" =0A= followed by a typename-type which is actually an array type. According to = =0A= standard, function signature is calculated by dropping so-called =0A= "top-level-cv-qualifier". As a result, the templater specialization complai= ns =0A= no matching to declaration can be found because specialization has const an= d =0A= template function declaration doesn't have const which is dropped as mentio= ned.=0A= Obviously the template function declaration should NOT drop the const. But = why?=0A= Let's review the procedure of standard first.=0A= (https://timsong-cpp.github.io/cppwp/dcl.fct#5.sentence-3)=0A= =0A= "After determining the type of each parameter, any parameter of type =93arr= ay of T=94 =0A= or of function type T is adjusted to be =93pointer to T=94. After producing= the list =0A= of parameter types, any top-level cv-qualifiers modifying a parameter type = are =0A= deleted when forming the function type."=0A= =0A= Please note the action of deleting top-level cv-qualifiers happens at last = stage =0A= after array type is converted to pointer type. More importantly, there are = two =0A= conditions:=0A= a) Each type must be able to be determined.=0A= b) The cv-qualifier must be top-level.=0A= Let's analysis if these two conditions can be met one by one.=0A= 1) Keyword "typename" indicates inside template it involves dependent name= =0A= =A0(https://timsong-cpp.github.io/cppwp/n4659/temp.res#2) for which the nam= e lookup =0A= can be postponed until template instantiation. Clearly the type of dependen= t =0A= name cannot be determined without name lookup. Then we can NOT proceed to n= ext =0A= step until concrete template argument type is determined during specializat= ion. =0A= 2) After =93array of T=94 is converted to =93pointer to T=94, the cv-qualif= iers are no =0A= longer top-level! Unfortunately in standard there is no definition =0A= of "top-level". Mr. Dan Saks's articals (https://www.dansaks.com/articles.s= html) =0A= are tremendous help! Especially this wonderful paper (https://www.dansaks.c= om/articles/2000-02%20Top-Level%20cv-Qualifiers%20in%20Function%20Parameter= s.pdf)=A0 =0A= discusses this topic in details. In one short sentence, the "const" before = =0A= array type is NOT top-level-cv-qualifier and should NOT be dropped.=0A= =0A= So, understanding the root cause makes the fix very clear: Let's NOT drop = =0A= cv-qualifier for typename-type inside template. Leave this task for templat= e=0A= substitution later when template specialization locks template argument typ= es.=0A= =0A= Similarly inside template, "decltype" may also include dependent name and = =0A= the best strategy for parser is to preserve all original declaration and = =0A= postpone the task till template substitution.=0A= =0A= Here is an interesting observation to share. Originally my fix is trying to= =0A= use function "resolve_typename_type" to see if the "typename-type" is indee= d=0A= an array type so as to decide whether the const should be dropped. It works= =0A= for cases of PR101402,PR102033(with a small fix of function), but cannot = =0A= succeed on cases of PR102034,PR102039. Especially PR102039 is impossible = =0A= because it depends on template argument. This helps me realize that parser = =0A= should not do any work if it cannot be 100% successful. All can wait.=0A= =0A= At last I want to acknowledge other efforts to tackle this core 1001/1322 f= rom =0A= PR92010 which is an irreplaceable different approach from this fix by doing= =0A= rebuilding template function signature during template substitution stage. = =0A= After all, this fix can only deal with dependent type started with "typenam= e"=0A= or "decltype" which is not the case of pr92010.=0A= =A0=0A= =0A= gcc/cp/ChangeLog:=0A= =0A= 2021-08-30=A0 qingzhe huang=A0 =0A= =0A= =A0=A0=A0=A0=A0=A0=A0 * decl.c (grokparms):=0A= =0A= gcc/testsuite/ChangeLog:=0A= =0A= 2021-08-30=A0 qingzhe huang=A0 =0A= =0A= =A0=A0=A0=A0=A0=A0=A0 * g++.dg/parse/pr101402.C: New test.=0A= =A0=A0=A0=A0=A0=A0=A0 * g++.dg/parse/pr102033.C: New test.=0A= =A0=A0=A0=A0=A0=A0=A0 * g++.dg/parse/pr102034.C: New test.=0A= =A0=A0=A0=A0=A0=A0=A0 * g++.dg/parse/pr102039.C: New test.=0A= =A0=A0=A0=A0=A0=A0=A0 * g++.dg/parse/pr102044.C: New test.=0A= =0A= =0A= diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c=0A= index e0c603aaab6..940c43ce707 100644=0A= --- a/gcc/cp/decl.c=0A= +++ b/gcc/cp/decl.c=0A= @@ -14384,7 +14384,16 @@ grokparms (tree parmlist, tree *parms)=0A= =A0=0A= =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 /* Top-level qualifiers on the parameters ar= e=0A= =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 ignored for function types.=A0 */= =0A= -=A0=A0=A0=A0=A0=A0=A0=A0 type =3D cp_build_qualified_type (type, 0);=0A= +=0A= +=A0=A0=A0=A0=A0=A0=A0=A0 int type_quals =3D 0;=0A= +=A0=A0=A0=A0=A0=A0=A0=A0 /* Inside template declaration, typename and decl= type indicating=0A= +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 dependent name and cv-qualifier are pres= erved until=0A= +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 template instantiation.=0A= +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 PR101402/PR102033/PR102034/PR102039/PR10= 2044 */=0A= +=A0=A0=A0=A0=A0=A0=A0=A0 if (processing_template_decl=0A= +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 && (TREE_CODE (type) =3D=3D TYP= ENAME_TYPE || TREE_CODE (type) =3D=3D DECLTYPE_TYPE))=0A= +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 type_quals =3D CP_TYPE_CO= NST_P(type);=0A= +=A0=A0=A0=A0=A0=A0=A0=A0 type =3D cp_build_qualified_type (type, type_qual= s);=0A= =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 if (TREE_CODE (type) =3D=3D METHOD_TYPE)=0A= =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 {=0A= =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 error ("parameter %qD invalidly = declared method type", decl);=0A= diff --git a/gcc/testsuite/g++.dg/parse/pr101402.C b/gcc/testsuite/g++.dg/p= arse/pr101402.C=0A= new file mode 100644=0A= index 00000000000..58d9c4f8542=0A= --- /dev/null=0A= +++ b/gcc/testsuite/g++.dg/parse/pr101402.C=0A= @@ -0,0 +1,5 @@=0A= +template struct A {=0A= +=A0=A0=A0=A0 typedef T arr[3];=0A= +};=0A= +template void f(const typename A::arr) { } // #1=0A= +template void f(const A::arr);=0A= diff --git a/gcc/testsuite/g++.dg/parse/pr102033.C b/gcc/testsuite/g++.dg/p= arse/pr102033.C=0A= new file mode 100644=0A= index 00000000000..0d5cc17620f=0A= --- /dev/null=0A= +++ b/gcc/testsuite/g++.dg/parse/pr102033.C=0A= @@ -0,0 +1,34 @@=0A= +/* {dg-do compile } */=0A= +/* {dg-options "-std=3Dc++11" } */=0A= +=0A= +namespace test1=0A= +{=0A= +template=0A= +struct A{=0A= +=A0=A0=A0=A0=A0=A0=A0 template=0A= +=A0=A0=A0=A0=A0=A0=A0 using Type=3DTB[3];=0A= +};=0A= +template=0A= +void f(const typename A::template Type){}=0A= +template <>=0A= +void f(const typename A::template Type){}=0A= +}=0A= +namespace test2=0A= +{=0A= +template=0A= +struct A{=0A= +=A0=A0=A0=A0=A0=A0=A0 template=0A= +=A0=A0=A0=A0=A0=A0=A0 struct B{=0A= +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 using TB_Alias=3DTB;=0A= +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 template=0A= +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 struct C{=0A= +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 type= def TC Arr3[3];=0A= +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 };=0A= +=A0=A0=A0=A0=A0=A0=A0 };=0A= +};=0A= +template=0A= +void f(const typename A::template B::template C<>::Arr3){}=0A= +template <>=0A= +void f(const typename A::template B::template C<>::A= rr3){}=0A= +}=0A= +=0A= diff --git a/gcc/testsuite/g++.dg/parse/pr102034.C b/gcc/testsuite/g++.dg/p= arse/pr102034.C=0A= new file mode 100644=0A= index 00000000000..37fdce52912=0A= --- /dev/null=0A= +++ b/gcc/testsuite/g++.dg/parse/pr102034.C=0A= @@ -0,0 +1,13 @@=0A= +/*{dg-do compile} */=0A= +template=0A= +struct A{=0A= +=A0=A0=A0=A0=A0=A0=A0 template=0A= +=A0=A0=A0=A0=A0=A0=A0 struct B{=0A= +=A0=A0=A0=A0=A0=A0=A0 typedef TB Arr3[3];=0A= +=A0=A0=A0=A0=A0=A0=A0 };=0A= +};=0A= +template=0A= +void f(const typename A::template B::Arr3){}=0A= +template <>=0A= +void f(const typename A::B::Arr3){}=0A= +=0A= diff --git a/gcc/testsuite/g++.dg/parse/pr102039.C b/gcc/testsuite/g++.dg/p= arse/pr102039.C=0A= new file mode 100644=0A= index 00000000000..25d3e77fd74=0A= --- /dev/null=0A= +++ b/gcc/testsuite/g++.dg/parse/pr102039.C=0A= @@ -0,0 +1,24 @@=0A= +namespace test1=0A= +{=0A= +struct A{=0A= +=A0=A0=A0=A0=A0=A0=A0 typedef int Arr3[3];=0A= +};=0A= +=0A= +template=0A= +void f(const typename T::Arr3){}=0A= +=0A= +template<>=0A= +void f(const int[3]){}=0A= +}=0A= +=0A= +namespace test2=0A= +{=0A= +struct A{=0A= +=A0=A0=A0=A0=A0=A0=A0 typedef int Arr3[3];=0A= +};=0A= +template=0A= +void f(const typename T::Arr3){}=0A= +template<>=0A= +void f(const int*){}=0A= +}=0A= +=0A= diff --git a/gcc/testsuite/g++.dg/parse/pr102044.C b/gcc/testsuite/g++.dg/p= arse/pr102044.C=0A= new file mode 100644=0A= index 00000000000..bef6a920b47=0A= --- /dev/null=0A= +++ b/gcc/testsuite/g++.dg/parse/pr102044.C=0A= @@ -0,0 +1,32 @@=0A= +/* {dg-do compile } */=0A= +/* {dg-options "-std=3Dc++11" } */=0A= +namespace test1=0A= +{=0A= +template=0A= +void f(const T[N]){}=0A= +=0A= +template=0A= +using fPtr=3Ddecltype(f)*;=0A= +=0A= +template=0A= +fPtr af[N]=3D{&f};=0A= +=0A= +template=0A= +void g(const decltype(af)){}=0A= +=0A= +template<>=0A= +void g<1,int>(const fPtr<1,int>[1]){}=0A= +}=0A= +=0A= +namespace test2=0A= +{=0A= +template =0A= +struct A{=0A= +T arr3[3];=0A= +};=0A= +template =0A= +void f(const decltype(A::arr3)){}=0A= +template <>=0A= +void f(const int[3]){}=0A= +}=0A= +=