[C++ PATCH] Fix unnecessary error when top-level cv-qualifiers is dropped (PR c++/101783)
The root cause of this bug is that it considers reference with cv-qualifiers as an error by generating value for variable "bad_quals". However, this is not correct for case of typedef. Here I quote spec: "Cv-qualified references are ill-formed except when the cv-qualifiers are introduced through the use of a typedef-name ([dcl.typedef], [temp.param]) or decltype-specifier ([dcl.type.decltype]), in which case the cv-qualifiers are ignored." 2021-08-09 Qingzhe Huang PR c++/101387 gcc/cp/ChangeLog: PR c++/101387 * tree.c (cp_build_qualified_type_real): Excluding typedef from error gcc/testsuite/ChangeLog: PR c++/101387 * g++.dg/parse/pr101783.C: New test. diff --git gcc/cp/tree.c gcc/cp/tree.c index 10b818d1370..a4ae3eee6d0 100644 --- gcc/cp/tree.c +++ gcc/cp/tree.c @@ -1361,11 +1361,18 @@ cp_build_qualified_type_real (tree type, /* A reference or method type shall not be cv-qualified. [dcl.ref], [dcl.fct]. This used to be an error, but as of DR 295 (in CD1) we always ignore extra cv-quals on functions. */ + /* Cv-qualified references are ill-formed except when the cv-qualifiers + are introduced through the use of a typedef-name ([dcl.typedef], + [temp.param]) or decltype-specifier ([dcl.type.decltype]), + in which case the cv-qualifiers are ignored. */ if (type_quals & (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE) && (TYPE_REF_P (type) || FUNC_OR_METHOD_TYPE_P (type))) { - if (TYPE_REF_P (type)) + if (TYPE_REF_P (type) + //A reference from typedef is not an error, but ignored. + && (!typedef_variant_p (type) || FUNC_OR_METHOD_TYPE_P (type))) bad_quals |= type_quals & (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE); type_quals &= ~(TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE); } diff --git gcc/testsuite/g++.dg/parse/pr101783.C gcc/testsuite/g++.dg/parse/pr101783.C new file mode 100644 index 000..8f8f8b1faeb --- /dev/null +++ gcc/testsuite/g++.dg/parse/pr101783.C @@ -0,0 +1,10 @@ +template struct A{ +typedef T& Type; +}; +template +void f(const typename A::Type){} +template<> +void f(const typename A::Type){} +struct B{}; +template<> +void f(const A::Type){}
[PATCH] c++: Fix unnecessary error when top-level cv-qualifiers is dropped [PR101783]
The root cause of this bug is that it considers reference with cv-qualifiers as an error by generating value for variable "bad_quals". However, this is not correct for case of typedef. Here I quote spec: "Cv-qualified references are ill-formed except when the cv-qualifiers are introduced through the use of a typedef-name ([dcl.typedef], [temp.param]) or decltype-specifier ([dcl.type.decltype]), in which case the cv-qualifiers are ignored." 2021-08-09 Qingzhe Huang PR c++/101387 gcc/cp/ChangeLog: PR c++/101387 * tree.c (cp_build_qualified_type_real): Excluding typedef from error gcc/testsuite/ChangeLog: PR c++/101387 * g++.dg/parse/pr101783.C: New test. diff --git gcc/cp/tree.c gcc/cp/tree.c index 10b818d1370..a4ae3eee6d0 100644 --- gcc/cp/tree.c +++ gcc/cp/tree.c @@ -1361,11 +1361,18 @@ cp_build_qualified_type_real (tree type, /* A reference or method type shall not be cv-qualified. [dcl.ref], [dcl.fct]. This used to be an error, but as of DR 295 (in CD1) we always ignore extra cv-quals on functions. */ + /* Cv-qualified references are ill-formed except when the cv-qualifiers + are introduced through the use of a typedef-name ([dcl.typedef], + [temp.param]) or decltype-specifier ([dcl.type.decltype]), + in which case the cv-qualifiers are ignored. */ if (type_quals & (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE) && (TYPE_REF_P (type) || FUNC_OR_METHOD_TYPE_P (type))) { - if (TYPE_REF_P (type)) + if (TYPE_REF_P (type) + //A reference from typedef is not an error, but ignored. + && (!typedef_variant_p (type) || FUNC_OR_METHOD_TYPE_P (type))) bad_quals |= type_quals & (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE); type_quals &= ~(TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE); } diff --git gcc/testsuite/g++.dg/parse/pr101783.C gcc/testsuite/g++.dg/parse/pr101783.C new file mode 100644 index 000..8f8f8b1faeb --- /dev/null +++ gcc/testsuite/g++.dg/parse/pr101783.C @@ -0,0 +1,10 @@ +template struct A{ +typedef T& Type; +}; +template +void f(const typename A::Type){} +template<> +void f(const typename A::Type){} +struct B{}; +template<> +void f(const A::Type){}
[PATCH] c++: Suppress error when cv-qualified reference is introduced by typedef [PR101783]
Reference with cv-qualifiers should be ignored instead of causing an error because standard accepts cv-qualified references introduced by typedef which is ignored. Therefore, the fix prevents GCC from reporting error by not setting variable "bad_quals" in case the reference is introduced by typedef. Still the cv-qualifier is silently ignored. Here I quote spec (https://timsong-cpp.github.io/cppwp/dcl.ref#1): "Cv-qualified references are ill-formed except when the cv-qualifiers are introduced through the use of a typedef-name ([dcl.typedef], [temp.param]) or decltype-specifier ([dcl.type.decltype]), in which case the cv-qualifiers are ignored." PR c++/101783 gcc/cp/ChangeLog: 2021-08-27 qingzhe huang * tree.c (cp_build_qualified_type_real): gcc/testsuite/ChangeLog: 2021-08-27 qingzhe huang * g++.dg/parse/pr101783.C: New test. diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index 8840932dba2..7aa4318a574 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -1356,12 +1356,22 @@ cp_build_qualified_type_real (tree type, /* A reference or method type shall not be cv-qualified. [dcl.ref], [dcl.fct]. This used to be an error, but as of DR 295 (in CD1) we always ignore extra cv-quals on functions. */ + + /* PR 101783 + Cv-qualified references are ill-formed except when the cv-qualifiers + are introduced through the use of a typedef-name ([dcl.typedef], + [temp.param]) or decltype-specifier ([dcl.type.decltype]), + in which case the cv-qualifiers are ignored. + */ if (type_quals & (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE) && (TYPE_REF_P (type) || FUNC_OR_METHOD_TYPE_P (type))) { - if (TYPE_REF_P (type)) + // do NOT set bad_quals when non-method reference is introduced by typedef. + if (TYPE_REF_P (type) + && (!typedef_variant_p (type) || FUNC_OR_METHOD_TYPE_P (type))) bad_quals |= type_quals & (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE); + // non-method reference introduced by typedef is also dropped silently type_quals &= ~(TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE); } diff --git a/gcc/testsuite/g++.dg/parse/pr101783.C b/gcc/testsuite/g++.dg/parse/pr101783.C new file mode 100644 index 000..4e0a435dd0b --- /dev/null +++ b/gcc/testsuite/g++.dg/parse/pr101783.C @@ -0,0 +1,5 @@ +template struct A{ +typedef T& Type; +}; +template void f(const typename A::Type){} +template <> void f(const typename A::Type){}
[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]
These bugs are considered duplicate cases of PR51851 which has been suspended since 2012, an issue known as "core1001/1322". Considering this background, it deserves a long comment to explain. Many people believed the root cause of this family of bugs is related with the nature of how and when the array type is converted to pointer type during function signature is calculated. This is true, but we may need to go into details to understand the exact reason. There is a pattern for these bugs(PR101402,PR102033,PR102034,PR102039). In the template function declaration, the function parameter is consisted of a "const" followed by a typename-type which is actually an array type. According to standard, function signature is calculated by dropping so-called "top-level-cv-qualifier". As a result, the templater specialization complains no matching to declaration can be found because specialization has const and template function declaration doesn't have const which is dropped as mentioned. Obviously the template function declaration should NOT drop the const. But why? Let's review the procedure of standard first. (https://timsong-cpp.github.io/cppwp/dcl.fct#5.sentence-3) "After determining the type of each parameter, any parameter of type “array of T” or of function type T is adjusted to be “pointer to T”. After producing the list of parameter types, any top-level cv-qualifiers modifying a parameter type are deleted when forming the function type." Please note the action of deleting top-level cv-qualifiers happens at last stage after array type is converted to pointer type. More importantly, there are two conditions: a) Each type must be able to be determined. b) The cv-qualifier must be top-level. Let's analysis if these two conditions can be met one by one. 1) Keyword "typename" indicates inside template it involves dependent name (https://timsong-cpp.github.io/cppwp/n4659/temp.res#2) for which the name lookup can be postponed until template instantiation. Clearly the type of dependent name cannot be determined without name lookup. Then we can NOT proceed to next step until concrete template argument type is determined during specialization. 2) After “array of T” is converted to “pointer to T”, the cv-qualifiers are no longer top-level! Unfortunately in standard there is no definition of "top-level". Mr. Dan Saks's articals (https://www.dansaks.com/articles.shtml) are tremendous help! Especially this wonderful paper (https://www.dansaks.com/articles/2000-02%20Top-Level%20cv-Qualifiers%20in%20Function%20Parameters.pdf) discusses this topic in details. In one short sentence, the "const" before array type is NOT top-level-cv-qualifier and should NOT be dropped. So, understanding the root cause makes the fix very clear: Let's NOT drop cv-qualifier for typename-type inside template. Leave this task for template substitution later when template specialization locks template argument types. Similarly inside template, "decltype" may also include dependent name and the best strategy for parser is to preserve all original declaration and postpone the task till template substitution. Here is an interesting observation to share. Originally my fix is trying to use function "resolve_typename_type" to see if the "typename-type" is indeed an array type so as to decide whether the const should be dropped. It works for cases of PR101402,PR102033(with a small fix of function), but cannot succeed on cases of PR102034,PR102039. Especially PR102039 is impossible because it depends on template argument. This helps me realize that parser should not do any work if it cannot be 100% successful. All can wait. At last I want to acknowledge other efforts to tackle this core 1001/1322 from PR92010 which is an irreplaceable different approach from this fix by doing rebuilding template function signature during template substitution stage. After all, this fix can only deal with dependent type started with "typename" or "decltype" which is not the case of pr92010. gcc/cp/ChangeLog: 2021-08-30 qingzhe huang * decl.c (grokparms): gcc/testsuite/ChangeLog: 2021-08-30 qingzhe huang * g++.dg/parse/pr101402.C: New test. * g++.dg/parse/pr102033.C: New test. * g++.dg/parse/pr102034.C: New test. * g++.dg/parse/pr102039.C: New test. * g++.dg/parse/pr102044.C: New test. diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index e0c603aaab6..940c43ce707 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -14384,7 +14384,16 @@ grokparms (tree parmlist, tree *parms) /* Top-level qualifiers on the parameters are ignored for function types. */ - type = cp_build_qualified_type (type, 0); + + int type_quals = 0; + /* Inside template declaration, typename and decltype indicating +dependent name and cv-qualifier are preserved until +template instantiation. +PR101402/PR102033/PR10
*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]
These bugs are considered duplicate cases of PR51851 which has been suspended since 2012, an issue known as "core1001/1322". Considering this background, it deserves a long comment to explain. Many people believed the root cause of this family of bugs is related with the nature of how and when the array type is converted to pointer type during function signature is calculated. This is true, but we may need to go into details to understand the exact reason. There is a pattern for these bugs(PR101402,PR102033,PR102034,PR102039). In the template function declaration, the function parameter is consisted of a "const" followed by a typename-type which is actually an array type. According to standard, function signature is calculated by dropping so-called "top-level-cv-qualifier". As a result, the templater specialization complains no matching to declaration can be found because specialization has const and template function declaration doesn't have const which is dropped as mentioned. Obviously the template function declaration should NOT drop the const. But why? Let's review the procedure of standard first. (https://timsong-cpp.github.io/cppwp/dcl.fct#5.sentence-3) "After determining the type of each parameter, any parameter of type “array of T” or of function type T is adjusted to be “pointer to T”. After producing the list of parameter types, any top-level cv-qualifiers modifying a parameter type are deleted when forming the function type." Please note the action of deleting top-level cv-qualifiers happens at last stage after array type is converted to pointer type. More importantly, there are two conditions: a) Each type must be able to be determined. b) The cv-qualifier must be top-level. Let's analysis if these two conditions can be met one by one. 1) Keyword "typename" indicates inside template it involves dependent name (https://timsong-cpp.github.io/cppwp/n4659/temp.res#2) for which the name lookup can be postponed until template instantiation. Clearly the type of dependent name cannot be determined without name lookup. Then we can NOT proceed to next step until concrete template argument type is determined during specialization. 2) After “array of T” is converted to “pointer to T”, the cv-qualifiers are no longer top-level! Unfortunately in standard there is no definition of "top-level". Mr. Dan Saks's articals (https://www.dansaks.com/articles.shtml) are tremendous help! Especially this wonderful paper (https://www.dansaks.com/articles/2000-02%20Top-Level%20cv-Qualifiers%20in%20Function%20Parameters.pdf) discusses this topic in details. In one short sentence, the "const" before array type is NOT top-level-cv-qualifier and should NOT be dropped. So, understanding the root cause makes the fix very clear: Let's NOT drop cv-qualifier for typename-type inside template. Leave this task for template substitution later when template specialization locks template argument types. Similarly inside template, "decltype" may also include dependent name and the best strategy for parser is to preserve all original declaration and postpone the task till template substitution. Here is an interesting observation to share. Originally my fix is trying to use function "resolve_typename_type" to see if the "typename-type" is indeed an array type so as to decide whether the const should be dropped. It works for cases of PR101402,PR102033(with a small fix of function), but cannot succeed on cases of PR102034,PR102039. Especially PR102039 is impossible because it depends on template argument. This helps me realize that parser should not do any work if it cannot be 100% successful. All can wait. At last I want to acknowledge other efforts to tackle this core 1001/1322 from PR92010 which is an irreplaceable different approach from this fix by doing rebuilding template function signature during template substitution stage. After all, this fix can only deal with dependent type started with "typename" or "decltype" which is not the case of pr92010. gcc/cp/ChangeLog: 2021-08-30 qingzhe huang * decl.c (grokparms): gcc/testsuite/ChangeLog: 2021-08-30 qingzhe huang * g++.dg/parse/pr101402.C: New test. * g++.dg/parse/pr102033.C: New test. * g++.dg/parse/pr102034.C: New test. * g++.dg/parse/pr102039.C: New test. * g++.dg/parse/pr102044.C: New test. diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index e0c603aaab6..940c43ce707 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -14384,7 +14384,16 @@ grokparms (tree parmlist, tree *parms) /* Top-level qualifiers on the parameters are ignored for function types. */ - type = cp_build_qualified_type (type, 0); + + int type_quals = 0; + /* Inside template declaration, typename and decltype indicating + dependent name and cv-qualifier are preserved until + template instantiation. + PR101402/PR102033/PR
*PING* Re: [PATCH] c++: Suppress error when cv-qualified reference is introduced by typedef [PR101783]
Reference with cv-qualifiers should be ignored instead of causing an error because standard accepts cv-qualified references introduced by typedef which is ignored. Therefore, the fix prevents GCC from reporting error by not setting variable "bad_quals" in case the reference is introduced by typedef. Still the cv-qualifier is silently ignored. Here I quote spec (https://timsong-cpp.github.io/cppwp/dcl.ref#1): "Cv-qualified references are ill-formed except when the cv-qualifiers are introduced through the use of a typedef-name ([dcl.typedef], [temp.param]) or decltype-specifier ([dcl.type.decltype]), in which case the cv-qualifiers are ignored." PR c++/101783 gcc/cp/ChangeLog: 2021-08-27 qingzhe huang * tree.c (cp_build_qualified_type_real): gcc/testsuite/ChangeLog: 2021-08-27 qingzhe huang * g++.dg/parse/pr101783.C: New test. diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index 8840932dba2..7aa4318a574 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -1356,12 +1356,22 @@ cp_build_qualified_type_real (tree type, /* A reference or method type shall not be cv-qualified. [dcl.ref], [dcl.fct]. This used to be an error, but as of DR 295 (in CD1) we always ignore extra cv-quals on functions. */ + + /* PR 101783 + Cv-qualified references are ill-formed except when the cv-qualifiers + are introduced through the use of a typedef-name ([dcl.typedef], + [temp.param]) or decltype-specifier ([dcl.type.decltype]), + in which case the cv-qualifiers are ignored. + */ if (type_quals & (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE) && (TYPE_REF_P (type) || FUNC_OR_METHOD_TYPE_P (type))) { - if (TYPE_REF_P (type)) + // do NOT set bad_quals when non-method reference is introduced by typedef. + if (TYPE_REF_P (type) + && (!typedef_variant_p (type) || FUNC_OR_METHOD_TYPE_P (type))) bad_quals |= type_quals & (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE); + // non-method reference introduced by typedef is also dropped silently type_quals &= ~(TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE); } diff --git a/gcc/testsuite/g++.dg/parse/pr101783.C b/gcc/testsuite/g++.dg/parse/pr101783.C new file mode 100644 index 000..4e0a435dd0b --- /dev/null +++ b/gcc/testsuite/g++.dg/parse/pr101783.C @@ -0,0 +1,5 @@ +template struct A{ + typedef T& Type; +}; +template void f(const typename A::Type){} +template <> void f(const typename A::Type){}
Re: *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]
Hi Jason, Sorry for not noticing your response. >>Unfortunately, your patch breaks >> >>template >>struct A >>{ >> void f(T); >>}; >>template >>void A::f(const T) >>{ } 1. Perhaps I misunderstand your comment, but my patch does NOT fix this issue. Neither does current GCC fix this code, if it is incorrect grammatically. In other words, tested in www.godbolt.org and all major compilers accept it. And my patch does NOT affects GCC current behavior, meaning my patched GCC still accepts it like now. So, I don't think my patch breaks it because this code is never fixed. (Whether this code is correct or not, I keep an open mind.) >>which is certainly questionable code, but is currently also accepted by >>clang and EDG compilers. 2. Like I said above, I am not even sure if it is an issue since most compilers accept it. But my patch does NOT touch this issue at all. In essential, my patch ONLY deals with dependent type starting with keyword "typename" or "decltype". Just like my email subject, my patch only fixes one particular case of this "family" of bugs, that is "typename" or "decltype" cases. >>Why doesn't the PR92010 fix address these testcases as well? 3. PR92010 creates new functions of "rebuild_function_or_method_type" and by using gdb to trace PR101402 code as following: template struct A { typedef T arr[3]; }; template void f(const typename A::arr) { }// #1 template void f(const A::arr); // #2 I added some print function declaration code before and after calling "maybe_rebuild_function_decl_type" to print out its parameter "r" which is function declaration inside "tsubst_function_decl". Here is the result: a) Before calling, the function declaration is "void f(int*)" and after calling, it is adjusted to correct one as "void f(const int*)". However, after this line "SET_DECL_IMPLICIT_INSTANTIATION (r);", it fallback to original dependent type as "void f(typename A::arr) [with T = int; typename A::arr = int [3]]" till end. This completely defeats the purpose of template substitution effort. b) On the other hand, by screening input parameter of "rebuild_function_or_method_type", I can see it is using an incorrect function type as "void(typename A::arr)" which already drops "const" prematurely. This is due to previous #1 template function declaration parsing. So, This gives us the clear idea of the root cause of this kind of bugs. It happens during template function declaration stage #1 when producing template declarator. Instead of doing a later-correction-effort in PR92010, my patch tries to at least avoid dropping "const" in case of "typename" and "decltype" during template function declaration stage in #1. Best regards, Qingzhe Huang From: Jason Merrill Sent: September 24, 2021 3:11 PM To: nick huang ; gcc-patches@gcc.gnu.org Subject: Re: *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] I already responded to this patch: https://gcc.gnu.org/pipermail/gcc-patches/2021-September/579527.html
Re: [PATCH] c++: Suppress error when cv-qualified reference is introduced by typedef [PR101783]
Hi Jason, 1. Thank you very much for your detailed comments for my patch and I really appreciate it! Here is my revised patch: The root cause of this bug is that it considers reference with cv-qualifiers as an error by generating value for variable "bad_quals". However, this is not correct for case of typedef. Here I quote spec: "Cv-qualified references are ill-formed except when the cv-qualifiers are introduced through the use of a typedef-name ([dcl.typedef], [temp.param]) or decltype-specifier ([dcl.type.decltype]), in which case the cv-qualifiers are ignored." 2021-09-25 qingzhe huang gcc/cp/ PR c++/101783 * tree.c (cp_build_qualified_type_real): gcc/testsuite/ PR c++/101783 * g++.dg/parse/pr101783.C: New test. -- next part -- diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index 8840932dba2..d5c8daeb340 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -1356,11 +1356,18 @@ cp_build_qualified_type_real (tree type, /* A reference or method type shall not be cv-qualified. [dcl.ref], [dcl.fct]. This used to be an error, but as of DR 295 (in CD1) we always ignore extra cv-quals on functions. */ + + /* Cv-qualified references are ill-formed except when the cv-qualifiers + are introduced through the use of a typedef-name ([dcl.typedef], + [temp.param]) or decltype-specifier ([dcl.type.decltype]), + in which case the cv-qualifiers are ignored. + */ if (type_quals & (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE) && (TYPE_REF_P (type) || FUNC_OR_METHOD_TYPE_P (type))) { - if (TYPE_REF_P (type)) + if (TYPE_REF_P (type) + && (!typedef_variant_p (type) || FUNC_OR_METHOD_TYPE_P (type))) bad_quals |= type_quals & (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE); type_quals &= ~(TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE); } diff --git a/gcc/testsuite/g++.dg/parse/pr101783.C b/gcc/testsuite/g++.dg/parse/pr101783.C new file mode 100644 index 000..4e0a435dd0b --- /dev/null +++ b/gcc/testsuite/g++.dg/parse/pr101783.C @@ -0,0 +1,5 @@ +template struct A{ +typedef T& Type; +}; +template void f(const typename A::Type){} +template <> void f(const typename A::Type){} 2. > In Jonathan's earlier reply he asked how you tested the patch; this > message still doesn't say anything about that. I communicated with Mr. Jonathan in private email, worrying my naive question might pollute the public maillist. The following is major part of this communication and I attached original part in attachment. >>>How has this patch been tested? Have you bootstrapped the compiler and >>>run the full testsuite? Here is how I am doing: a) build original 10.2.0 from scratch and make check to get both "testsuite/gcc/gcc.sum" and "testsuite/g++/g++.sum". b) apply my patch and build from scratch and make check to get both two files above. c) compare two run's *.sum files to see if there is any difference. (Later I realized there is tool "contrib/compare_tests" is a good help of doing so.) 3. > What is the legal status of your contributions? I thought small patch didn't require assignment. However, I just sent email to ass...@gnu.org to request assignment. Alternatively, I am not sure if adding this "signoff" tag in submission will help? Signed-off-by: qingzhe huang Thank you again! > On 8/28/21 07:54, nick huang via Gcc-patches wrote: > > Reference with cv-qualifiers should be ignored instead of causing an error > > because standard accepts cv-qualified references introduced by typedef which > > is ignored. > > Therefore, the fix prevents GCC from reporting error by not setting variable > > "bad_quals" in case the reference is introduced by typedef. Still the > > cv-qualifier is silently ignored. > > Here I quote spec (https://timsong-cpp.github.io/cppwp/dcl.ref#1): > > "Cv-qualified references are ill-formed except when the cv-qualifiers > > are introduced through the use of a typedef-name ([dcl.typedef], > > [temp.param]) or decltype-specifier ([dcl.type.decltype]), > > in which case the cv-qualifiers are ignored." > > > > PR c++/101783 > > > > gcc/cp/ChangeLog: > > > > 2021-08-27 qingzhe huang > > > > * tree.c (cp_build_qualified_type_real): > > The git commit verifier rejects this commit message with > > Checking 1fa0fbcdd15adf936ab4fae584f841beb35da1bb: FAILED ERR: missing > description of a change: > " * tree.c (cp_build_qualified_type_real):" > > (your initial patch had a description here, you just need to copy it over) > > ERR: PR 101783 in subject but not in changelog: > "c++: Suppress error when cv-qualified reference is introduced by > typ
Re: *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]
>>template >>struct A >>{ >> void f(T); >>}; >> >>template >>void A::f(const T) >>{ } >> >>which is certainly questionable code, but is currently also accepted by >>clang and EDG compilers. I just found out that clang actually correctly reject this code during specialization. (https://www.godbolt.org/z/evjvhqqoo) It all depends on explicit argument which may turn "const" into top-level-cv-qualifier or not. For example, when argument is "int[3]", the function signature of specialization will have to keep the const because it is no longer top-level cv qualifier. template<> void A::f(const int*){} // not matching declaration "void(int*)" Obviously when explicit argument is "int", the const would be dropped and specialization matches declaration. i.e. template<> void A::f(int){} // this matches declaration "void(int)" So, clang is correct to NOT reject template definition when there is no specialization yet. As a comparison, GCC is not able to reject incorrect specialization. Should we file this bug? Or just add this as test case to original 1001 core issue? Again, my patch cannot deal this case as it is not "typename". We may have to fix "tsubst_function_decl" to see any workaround of line "SET_DECL_IMPLICIT_INSTANTIATION (r);" (See my previous email https://gcc.gnu.org/pipermail/gcc-patches/2021-September/580260.html) This macro "DECL_USE_TEMPLATE" is set to 1. However, the comment says "1" is for "implicit specialization", but we are actually dealing with "partial or explicit specialization" which is "2". Here I quote comment from cp-tree.h /* Nonzero iff NODE is a specialization of a template. The value indicates the type of specializations: 1=implicit instantiation 2=partial or explicit specialization, e.g.: template <> int min (int, int), 3=explicit instantiation, e.g.: template int min (int, int); Note that NODE will be marked as a specialization even if the template it is instantiating is not a primary template. For example, given: template struct O { void f(); struct I {}; }; both O::f and O::I will be marked as instantiations. If DECL_USE_TEMPLATE is nonzero, then DECL_TEMPLATE_INFO will also be non-NULL. */
Re: [PATCH] c++: Suppress error when cv-qualified reference is introduced by typedef [PR101783]
>>You may need to run contrib/gcc-git-customization.sh to get the git >>gcc-verify command. I re-setup and can use git gcc-verify. Now I can see it rejects because I forgot to add a description of modified file. Now that it passes gcc-verify and I attach the changelog as attachment. Thank you again for your patient explanation and help! On 9/26/21 21:31, nick huang via Gcc-patches wrote: > Hi Jason, > > 1. Thank you very much for your detailed comments for my patch and I really > appreciate it! Here is my revised patch: > > The root cause of this bug is that it considers reference with > cv-qualifiers as an error by generating value for variable "bad_quals". > However, this is not correct for case of typedef. Here I quote spec: > "Cv-qualified references are ill-formed except when the cv-qualifiers > are introduced through the use of a typedef-name ([dcl.typedef], > [temp.param]) or decltype-specifier ([dcl.type.decltype]), > in which case the cv-qualifiers are ignored." > > 2021-09-25 qingzhe huang > > gcc/cp/ > PR c++/101783 > * tree.c (cp_build_qualified_type_real): git gcc-verify still rejects this line with ERR: missing description of a change: " * tree.c (cp_build_qualified_type_real):" You may need to run contrib/gcc-git-customization.sh to get the git gcc-verify command. > gcc/testsuite/ > PR c++/101783 > * g++.dg/parse/pr101783.C: New test. > -- next part -- Please drop this line, it breaks git gcc-verify when I apply the patch with git am. The patch should start immediately after the ChangeLog entries. > diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c > index 8840932dba2..d5c8daeb340 100644 > --- a/gcc/cp/tree.c > +++ b/gcc/cp/tree.c > @@ -1356,11 +1356,18 @@ cp_build_qualified_type_real (tree type, > /* A reference or method type shall not be cv-qualified. > [dcl.ref], [dcl.fct]. This used to be an error, but as of DR 295 > (in CD1) we always ignore extra cv-quals on functions. */ > + > + /* Cv-qualified references are ill-formed except when the cv-qualifiers In my previous reply I meant please add "[dcl.ref]/1" at the beginning of this comment. > + are introduced through the use of a typedef-name ([dcl.typedef], > + [temp.param]) or decltype-specifier ([dcl.type.decltype]), > + in which case the cv-qualifiers are ignored. > + */ > if (type_quals & (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE) > && (TYPE_REF_P (type) > || FUNC_OR_METHOD_TYPE_P (type))) > { > - if (TYPE_REF_P (type)) > + if (TYPE_REF_P (type) > + && (!typedef_variant_p (type) || FUNC_OR_METHOD_TYPE_P (type))) > bad_quals |= type_quals & (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE); > type_quals &= ~(TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE); > } > diff --git a/gcc/testsuite/g++.dg/parse/pr101783.C > b/gcc/testsuite/g++.dg/parse/pr101783.C > new file mode 100644 > index 000..4e0a435dd0b > --- /dev/null > +++ b/gcc/testsuite/g++.dg/parse/pr101783.C > @@ -0,0 +1,5 @@ > +template struct A{ > + typedef T& Type; > +}; > +template void f(const typename A::Type){} > +template <> void f(const typename A::Type){} > > > > 2. >> In Jonathan's earlier reply he asked how you tested the patch; this >> message still doesn't say anything about that. > I communicated with Mr. Jonathan in private email, worrying my naive question > might pollute the public maillist. The following is major part of this > communication and I attached original part in attachment. > >>>> How has this patch been tested? Have you bootstrapped the compiler and >>>> run the full testsuite? > Here is how I am doing: > a) build original 10.2.0 from scratch and make check to get both > "testsuite/gcc/gcc.sum" > and "testsuite/g++/g++.sum". > b) apply my patch and build from scratch and make check to get both two files > above. > c) compare two run's *.sum files to see if there is any difference. > > (Later I realized there is tool "contrib/compare_tests" is a good help of >doing so.) > > 3. >> What is the legal status of your contributions? > I thought small patch didn't require assignment. However, I just sent email > to ass...@gnu.org to request assignment. > Alternatively, I am not sure if adding this "signoff" tag in submission will > help? > Signed-off-by: qingzhe huang > > > Thank you again! > > >> On 8/28/21 07:54, nick huang via Gcc-patches wrote: >>> Reference with cv-qualifiers should be ignored instead of
Re: [PATCH] c++: Suppress error when cv-qualified reference is introduced by typedef [PR101783]
> gcc-verify still fails with this version: > > > ERR: line should start with a tab: "PR c++/101783" > > ERR: line should start with a tab: "* tree.c > > (cp_build_qualified_type_real): Excluding typedef from error" > > ERR: line should start with a tab: "PR c++/101783" > > ERR: line should start with a tab: "* g++.dg/parse/pr101783.C: New > > test." > It might work better to attach the output of git format-patch. Sorry for my clumsy copy/paste from git commit message. I now attach git format-patch output file as attachment. Also maybe for a little convenience of your work, I also attach the original commit message file when I do git commit -F. > Also, your commit subject line is too long, at 83 characters: It must be > under 75 characters, and preferably closer to 50. I might shorten it to Please go ahead. I will pay attention to this next time. Thank you! > A change description in the ChangeLog should use present tense > ("Exclude"), have a period at the end, and line wrap at 75 characters > like the rest of the commit message. So, > > * tree.c (cp_build_qualified_type_real): Exclude typedef from > error. > Modified as suggested. > > + ([dcl.type.decltype]),in which case the cv-qualifiers are ignored. > > + */ > > We usually don't put */ on its own line. Adjusted. Once again I thank you for your patience and really appreciate it. On Fri, Oct 1, 2021 at 9:29 AM Jason Merrill via Gcc-patches wrote: > > On 9/30/21 14:24, nick huang wrote: > >>> You may need to run contrib/gcc-git-customization.sh to get the git > >>> gcc-verify command. > > I re-setup and can use git gcc-verify. Now I can see it rejects because I > > forgot to add a > > description of modified file. Now that it passes gcc-verify and I attach > > the changelog > > as attachment. > > > > Thank you again for your patient explanation and help! > > You're welcome, thanks for your patience as well! Unfortunately, git > gcc-verify still fails with this version: > > > ERR: line should start with a tab: "PR c++/101783" > > ERR: line should start with a tab: "* tree.c > > (cp_build_qualified_type_real): Excluding typedef from error" > > ERR: line should start with a tab: "PR c++/101783" > > ERR: line should start with a tab: "* g++.dg/parse/pr101783.C: New > > test." > > It might work better to attach the output of git format-patch. > > Also, your commit subject line is too long, at 83 characters: It must be > under 75 characters, and preferably closer to 50. I might shorten it to > > c++: cv-qualified ref introduced by typedef [PR101783] > > > * tree.c (cp_build_qualified_type_real): Excluding typedef from error > > A change description in the ChangeLog should use present tense > ("Exclude"), have a period at the end, and line wrap at 75 characters > like the rest of the commit message. So, > > * tree.c (cp_build_qualified_type_real): Exclude typedef from > error. > > > + ([dcl.type.decltype]),in which case the cv-qualifiers are ignored. > > + */ > > We usually don't put */ on its own line. > > Jason > -- nick huang/qingzhe huang http://www.staroceans.com http://www.staroceans.com/english.htm The root cause of this bug is that it considers reference with cv-qualifiers as an error by generating value for variable "bad_quals". However, this is not correct for case of typedef. Here I quote spec [dcl.ref]/1 : "Cv-qualified references are ill-formed except when the cv-qualifiers are introduced through the use of a typedef-name ([dcl.typedef], [temp.param]) or decltype-specifier ([dcl.type.decltype]), in which case the cv-qualifiers are ignored." 2021-09-30 qingzhe huang gcc/cp/ChangeLog: PR c++/101783 * tree.c (cp_build_qualified_type_real): Exclude typedef from error. gcc/testsuite/ChangeLog: PR c++/101783 * g++.dg/parse/pr101783.C: New test. From e592a475030d99647de736d294cb3c6a7588af49 Mon Sep 17 00:00:00 2001 From: qingzhe huang Date: Fri, 1 Oct 2021 10:46:35 -0400 Subject: [PATCH] The root cause of this bug is that it considers reference with cv-qualifiers as an error by generating value for variable "bad_quals". However, this is not correct for case of typedef. Here I quote spec [dcl.ref]/1 : "Cv-qualified references are ill-formed except when the cv-qualifiers are introduced through the use of a typedef-name ([dcl.typedef], [temp.param]) or decltype-specifier ([dcl.type.decltype]), in which case the cv-qualifiers are ignored." 2021-09-30 qingzhe huang gcc/cp/ChangeLog: PR c++/101783 * tree.c (cp_build_qualified_type_real): Exclude typedef from error. gcc/testsuite/ChangeLog: PR c++/101783 * g++.dg/parse/pr101783.C: New test. --- gcc/cp/tree.c | 9 - gcc/testsuite/g++.dg/parse/pr101783.C | 5 + 2 files changed, 13 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/g++.dg/parse/pr101783.C diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c inde
Re: [PATCH] c++: Suppress error when cv-qualified reference is introduced by typedef [PR101783]
> ...the subject line for the commit should be the first line of the > commit message, followed by a blank line, followed by the description of > the patch; without the subject line, git format-patch thought your whole > description was the subject of the patch. oh, I didn't realize this without your mentioning it. I read this guide (https://gcc.gnu.org/codingconventions.html#ChangeLogs) many times and still don't get this. I guess it was written long long ago. > I've corrected this and pushed the patch, thanks! I do thank you and without your help I might never accomplish this task. Once again appreciate your patient help! On Fri, Oct 1, 2021 at 11:46 AM Jason Merrill wrote: > > On 10/1/21 11:10, Nick Huang wrote: > >> gcc-verify still fails with this version: > >> > >>> ERR: line should start with a tab: "PR c++/101783" > >>> ERR: line should start with a tab: "* tree.c > >>> (cp_build_qualified_type_real): Excluding typedef from error" > >>> ERR: line should start with a tab: "PR c++/101783" > >>> ERR: line should start with a tab: "* g++.dg/parse/pr101783.C: New > >>> test." > > > >> It might work better to attach the output of git format-patch. > > Sorry for my clumsy copy/paste from git commit message. I now attach > > git format-patch output > > file as attachment. Also maybe for a little convenience of your work, > > I also attach the original > > commit message file when I do git commit -F. > > Thanks, but that isn't necessary; it should be the same in the > format-patch output, except... > > > From e592a475030d99647de736d294cb3c6a7588af49 Mon Sep 17 00:00:00 2001 > > From: qingzhe huang > > Date: Fri, 1 Oct 2021 10:46:35 -0400 > > Subject: [PATCH] The root cause of this bug is that it considers reference > > with cv-qualifiers as an error by generating value for variable > > "bad_quals". > > However, this is not correct for case of typedef. Here I quote spec > > [dcl.ref]/1 : "Cv-qualified references are ill-formed except when the > > cv-qualifiers are introduced through the use of a typedef-name > > ([dcl.typedef], [temp.param]) or decltype-specifier ([dcl.type.decltype]), > > in > > which case the cv-qualifiers are ignored." > > ...the subject line for the commit should be the first line of the > commit message, followed by a blank line, followed by the description of > the patch; without the subject line, git format-patch thought your whole > description was the subject of the patch. > > I've corrected this and pushed the patch, thanks! > > Jason > -- nick huang/qingzhe huang http://www.staroceans.com http://www.staroceans.com/english.htm
[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, PR102
Hi Jason, I made a little improvement of my fix by including template type parameter to not dropping cv-const because they are similar to dependent type which you cannot determine whether they are top-level cv-qualifier or not until instantiation. + if (processing_template_decl + && (TREE_CODE (type) == TYPENAME_TYPE + || TREE_CODE (type) == DECLTYPE_TYPE ++ || TREE_CODE (type) == TEMPLATE_TYPE_PARM // this is new + ) +) 1. It fix your test case of template struct A{ void f(T); }; template void A::f(const T){ } template<> void A::f(const int*){} current GCC mistakenly accepts without considering the gap of missing "const" between declaration and out of line definition. clang correctly rejects it. (https://www.godbolt.org/z/qb9Tf99eK) and explains the cause nicely. My fix also rejects it. 2. It also fix a more obvious core1001 issue of free function as my previous fix only deals with typename/decltype cases. template void f(const T){} template<> void f(const int*){} Your comment is appreciated. thank you
Re: [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, PR102
Here I attach [PATCH-v2]. On Sun, Oct 3, 2021 at 7:14 AM Nick Huang wrote: > > Hi Jason, > > I made a little improvement of my fix by including template > type parameter to not dropping cv-const because they are similar to dependent > type which you cannot determine whether they are top-level cv-qualifier or not > until instantiation. > > + if (processing_template_decl > + && (TREE_CODE (type) == TYPENAME_TYPE > + || TREE_CODE (type) == DECLTYPE_TYPE > ++ || TREE_CODE (type) == TEMPLATE_TYPE_PARM // this is new > + ) > +) > > 1. It fix your test case of > template > struct A{ >void f(T); > }; > template > void A::f(const T){ } > template<> > void A::f(const int*){} > > current GCC mistakenly accepts without considering the gap of missing "const" > between declaration and out of line definition. clang correctly rejects it. > (https://www.godbolt.org/z/qb9Tf99eK) and explains the cause nicely. > My fix also rejects it. > > 2. It also fix a more obvious core1001 issue of free function as my previous > fix > only deals with typename/decltype cases. > template > void f(const T){} > template<> > void f(const int*){} > > Your comment is appreciated. > > thank you From 0d096262fc708edea825af713526b1ce1e9e689d Mon Sep 17 00:00:00 2001 From: qingzhe huang Date: Sun, 3 Oct 2021 16:00:29 -0400 Subject: [PATCH] Fix core1001/1322 by preserving const MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These bugs are considered duplicate cases of PR51851 which has been suspended since 2012, an issue known as "core1001/1322". Considering this background, it deserves a long comment to explain. Many people believed the root cause of this family of bugs is related with the nature of how and when the array type is converted to pointer type during function signature is calculated. This is true, but we may need to go into details to understand the exact reason. There is a pattern for these bugs(PR101402,PR102033,PR102034,PR102039). In the template function declaration, the function parameter is consisted of a "const" followed by a typename-type which is actually an array type. According to standard, function signature is calculated by dropping so- called "top-level-cv-qualifier". As a result, the templater specialization complains no matching to declaration can be found because specialization has const and template function declaration doesn't have const which is dropped as mentioned. Obviously the template function declaration should NOT drop the const. But why? Let's review the procedure of standard first. (https://timsong-cpp.github.io/cppwp/dcl.fct#5.sentence-3) "After determining the type of each parameter, any parameter of type “array of T” or of function type T is adjusted to be “pointer to T”. After producing the list of parameter types, any top-level cv-qualifiers modifying a parameter type are deleted when forming the function type." Please note the action of deleting top-level cv-qualifiers happens at last stage after array type is converted to pointer type. More importantly, there are two conditions: a) Each type must be able to be determined. b) The cv-qualifier must be top-level. Let's analysis if these two conditions can be met one by one. 1) Keyword "typename" indicates inside template it involves dependent name (https://timsong-cpp.github.io/cppwp/n4659/temp.res#2) for which the name lookup can be postponed until template instantiation. Clearly the type of dependent name cannot be determined without name lookup. Then we can NOT proceed to next step until concrete template argument type is determined during specialization. 2) After “array of T” is converted to “pointer to T”, the cv-qualifiers are no longer top-level! Unfortunately in standard there is no definition of "top-level". Mr. Dan Saks's articals (https://www.dansaks.com/articles.shtml) are tremendous help! Especially this wonderful paper (https://www.dansaks.com/articles/ 2000-02%20Top-Level%20cv-Qualifiers%20in%20Function%20Parameters.pdf) discusses this topic in details. In one short sentence, the "const" before array type is NOT top-level-cv-qualifier and should NOT be dropped. So, understanding the root cause makes the fix very clear: Let's NOT drop cv-qualifier for typename-type inside template. Leave this task for template substitution later when template specialization locks template argument types. Similarly inside template, "decltype" may also include dependent name and the best strategy for parser is to preserve all original declaration and postpone the task till template substitution. For template type parameter, it is obvious to follow similar strategy to not drop cv-const and leave it till instantiation. Here is an interesting observation to share. Originally my fix is trying to use function "resolve_typename_type" to see if the "typename-type" is indeed an array type so as to decide whether the cons
Re: [PATCH] c++: Comment out announce_function to prevent ICE [PR102426]
I am terribly sorry for my typo of wrong PR #, it should be 102624. Please ignore this email thread and I resend the patch in next email with correct subject: [PATCH] c++: Comment out announce_function to prevent ICE [PR102624] Once again my apologies for spam. On Fri, Oct 8, 2021 at 12:31 AM qingzhe huang wrote: > > This "announce_function" is not a purely readonly > function. Instead it calls tsubst which modifies > global variable "current_function_decl". If it is > placed at parser code directory level, recursion > might happen and set/reset variable might interleave > and can cause ICE. No test case is provided because > this segment fault only occurs when compiler option > "-quiet" is not set which is usually set by driver. > That is why usual testcases cannot expose this issue. > Even though this issue usually doesn't affect endusers, > however, it is a headache for development. > > gcc/cp/ChangeLog: > PR c++/102426 > * decl.c (start_preparsed_function): Comment > out announce_function. > (emit_coro_helper): Comment out > announce_function. > > gcc/ChangeLog: > PR c++/102426 > * toplev.c (get_src_pwd): Add comment > to note announce_function usage. > > Signed-off-by: qingzhe huang > --- > gcc/cp/decl.c | 4 > gcc/toplev.c | 5 - > 2 files changed, 4 insertions(+), 5 deletions(-) > > diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c > index 2d30c790b93..94d3a2c1cba 100644 > --- a/gcc/cp/decl.c > +++ b/gcc/cp/decl.c > @@ -16904,9 +16904,6 @@ start_preparsed_function (tree decl1, tree attrs, int > flags) > where store_parm_decls will find them. */ >tree current_function_parms = DECL_ARGUMENTS (decl1); > > - /* Let the user know we're compiling this function. */ > - announce_function (decl1); > - >gcc_assert (DECL_INITIAL (decl1)); > >/* This function may already have been parsed, in which case just > @@ -17472,7 +17469,6 @@ emit_coro_helper (tree helper) >current_function_decl = helper; >begin_scope (sk_function_parms, NULL); >store_parm_decls (DECL_ARGUMENTS (helper)); > - announce_function (helper); >allocate_struct_function (helper, false); >cfun->language = ggc_cleared_alloc (); >poplevel (1, 0, 1); > diff --git a/gcc/toplev.c b/gcc/toplev.c > index 1bb1794be96..4a3ca1aef4a 100644 > --- a/gcc/toplev.c > +++ b/gcc/toplev.c > @@ -221,7 +221,10 @@ get_src_pwd (void) > } > > /* Called when the start of a function definition is parsed, > - this function prints on stderr the name of the function. */ > + this function prints on stderr the name of the function. > + NOTE: Do not use this function at directory gcc/cp level > + or below because it might recurse and interleave with > + function frame parsing which can cause crash. */ > void > announce_function (tree decl) > { > -- > 2.17.1 >
[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, PR102
First of all, I am sorry for my late response as I missed your email. I need to update my filter setup of gmail after switching from hotmail. >I think WILDCARD_TYPE_P is what you want, except... I will try this one. >Your patch rejects that testcase even without the specialization on >int[], which no other compiler I'm aware of does; Honestly I now realize this is a wakeup call for me as I have been trying to revert PR92010 approach for months as I at that time favor the early syntax-checking approach which is considered efficient. Now your testcase reveals me a realist practice that almost all compilers tolerate this seemingly user's definition error because: a) It actually follows the principle that template without instantiation might not give error. b) "const T" and "T" maybe turn out to be the same after instantiation as function parameter. So, I guess this is the real practical approach for most compilers to rebuild function signature from declaration only when instantiation. My approach stucks when GCC search declaration for definition because "T" and "const T" are two different CANONICAL types. So, I now guess that is why declarator deliberately drops cv-qualifers to tolerate your testcase. >You seem to have missed my September 28 mail that argued for fixing the >bug in determine_specialization that was preventing the 92010 fix from >handling these cases. I did try to see this approach, but I was stuck in a sidelined issue of PR102624 which relates to lambda-in-unevaluated-context. The point is that I thought PR92010 starts to satisfy this pt.c:tsubst_default_argument: gcc_assert (same_type_ignoring_top_level_qualifiers_p (type, parmtype)); But I think after introduction of lambda in unevaluated context, this may not be correct assertion. I could be wrong on this. However, i.e. template void spam(decltype([]{})* ptr=nullptr) { } void foo(){ spam(); } When rebuilding lambda type from declaration, it is always a unique different type. So, that is the reason I thought this rebuild function type approach is imperfect. In other words, it is no good to rebuild function type to satisfy this may-not-be-correct-assertion, Anyway, I now think PR92010 is practically a good approach and I will start testing your patch. Best regards,
Re: [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, PR102
hi Jason, IMHO, I think your patch probably finally solved this long-standing Core 1001 issue. Of course it is not up to me to say so. I just want to point out that it even solves the following case, even though it is more or less expected if concept and lambda all work expectedly. template concept IsLambdaAry3=__is_same(T, decltype(+[]{})[3]); template void bar(const T){} template<> void bar(const decltype(+[]{})[3]){} B.Regards,