[C++ PATCH] Fix unnecessary error when top-level cv-qualifiers is dropped (PR c++/101783)

2021-08-09 Thread nick huang via Gcc-patches
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]

2021-08-09 Thread nick huang via Gcc-patches
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]

2021-08-28 Thread nick huang via Gcc-patches
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]

2021-08-31 Thread nick huang via Gcc-patches
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]

2021-09-24 Thread nick huang via Gcc-patches
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]

2021-09-24 Thread nick huang via Gcc-patches
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]

2021-09-25 Thread nick huang via Gcc-patches
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]

2021-09-26 Thread nick huang via Gcc-patches
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]

2021-09-26 Thread nick huang via Gcc-patches
>>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]

2021-09-30 Thread nick huang via Gcc-patches
>>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]

2021-10-01 Thread Nick Huang via Gcc-patches
> 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]

2021-10-01 Thread Nick Huang via Gcc-patches
> ...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

2021-10-03 Thread Nick Huang via Gcc-patches
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

2021-10-03 Thread Nick Huang via Gcc-patches
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]

2021-10-07 Thread Nick Huang via Gcc-patches
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

2021-10-08 Thread Nick Huang via Gcc-patches
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

2021-10-14 Thread Nick Huang via Gcc-patches
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,