public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] c++: abbreviated function template return type rewriting [PR98990]
@ 2021-02-09 18:31 Patrick Palka
  2021-02-25 22:09 ` Patrick Palka
  0 siblings, 1 reply; 3+ messages in thread
From: Patrick Palka @ 2021-02-09 18:31 UTC (permalink / raw)
  To: gcc-patches

When an abbreviated function template has a complex placeholder return
type such auto& or auto**, the level adjustment performed by
splice_late_return_type directly replaces the 'auto' inside the original
return type with the level-adjusted 'auto', but that breaks
TYPE_CANONICAL caching.  Instead, we should rebuild the entire return
type using the adjusted 'auto'.

This patch makes this happen by tsubsting the original return type with
an argument vector that maps the original 'auto' to the adjusted 'auto'.
In passing, this patch also reverts the misguided changes to
find_type_usage in r10-6571 that made find_type_usage return a tree*
instead of a tree so as to discourage this kind of in-place type
modification.

It occurred to me that the constraint also needs to be rebuilt so that
it refers to the adjusted 'auto', but this oversight doesn't seem to
cause any issues at the moment due to how do_auto_deduction "manually"
substitutes the 'auto' inside the constraint before performing
satisfaction.  So this will instead be fixed as part of a broader rework
of placeholder type constraint checking.

Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for
trunk/10?

gcc/cp/ChangeLog:

	PR c++/98990
	* pt.c (splice_late_return_type): Rebuild the entire return type
	if we have to adjust the level of the auto.  Use
	TEMPLATE_TYPE_LEVEL for brevity.
	(type_uses_auto): Adjust call to find_type_usage.
	* type-utils.h (find_type_usage): Revert r10-6571 change that
	made this function return a pointer to the auto node.

gcc/testsuite/ChangeLog:

	PR c++/98990
	* g++.dg/concepts/abbrev8.C: New test.
---
 gcc/cp/pt.c                             | 39 +++++++++++++------------
 gcc/cp/type-utils.h                     | 23 +++++++--------
 gcc/testsuite/g++.dg/concepts/abbrev8.C | 22 ++++++++++++++
 3 files changed, 53 insertions(+), 31 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/concepts/abbrev8.C

diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index c5b0a9292db..46cd322fbf4 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -29601,22 +29601,25 @@ splice_late_return_type (tree type, tree late_return_type)
       return late_return_type;
     }
 
-  if (tree *auto_node = find_type_usage (&type, is_auto))
-    {
-      tree idx = get_template_parm_index (*auto_node);
-      if (TEMPLATE_PARM_LEVEL (idx) <= processing_template_decl)
-	{
-	  /* In an abbreviated function template we didn't know we were dealing
-	     with a function template when we saw the auto return type, so update
-	     it to have the correct level.  */
-	  tree new_auto = make_auto_1 (TYPE_IDENTIFIER (*auto_node), false);
-	  PLACEHOLDER_TYPE_CONSTRAINTS (new_auto)
-	    = PLACEHOLDER_TYPE_CONSTRAINTS (*auto_node);
-	  TYPE_CANONICAL (new_auto) = canonical_type_parameter (new_auto);
-	  new_auto = cp_build_qualified_type (new_auto, TYPE_QUALS (*auto_node));
-	  *auto_node = new_auto;
-	}
-    }
+  if (tree auto_node = find_type_usage (type, is_auto))
+    if (TEMPLATE_TYPE_LEVEL (auto_node) <= processing_template_decl)
+      {
+	/* In an abbreviated function template we didn't know we were dealing
+	   with a function template when we saw the auto return type, so rebuild
+	   the return type using an auto with the correct level.  */
+	tree new_auto = make_auto_1 (TYPE_IDENTIFIER (auto_node), false);
+	tree auto_vec = make_tree_vec (1);
+	TREE_VEC_ELT (auto_vec, 0) = new_auto;
+	tree targs = add_outermost_template_args (current_template_args (),
+						  auto_vec);
+	/* FIXME: We should also rebuild the constraint to refer to the new
+	   auto.  */
+	PLACEHOLDER_TYPE_CONSTRAINTS (new_auto)
+	  = PLACEHOLDER_TYPE_CONSTRAINTS (auto_node);
+	TYPE_CANONICAL (new_auto) = canonical_type_parameter (new_auto);
+	new_auto = cp_build_qualified_type (new_auto, TYPE_QUALS (auto_node));
+	return tsubst (type, targs, tf_none, NULL_TREE);
+      }
   return type;
 }
 
@@ -29661,10 +29664,8 @@ type_uses_auto (tree type)
       else
 	return NULL_TREE;
     }
-  else if (tree *tp = find_type_usage (&type, is_auto))
-    return *tp;
   else
-    return NULL_TREE;
+    return find_type_usage (type, is_auto);
 }
 
 /* Report ill-formed occurrences of auto types in ARGUMENTS.  If
diff --git a/gcc/cp/type-utils.h b/gcc/cp/type-utils.h
index 5551e8f5ef1..138fed6c51e 100644
--- a/gcc/cp/type-utils.h
+++ b/gcc/cp/type-utils.h
@@ -20,22 +20,21 @@ along with GCC; see the file COPYING3.  If not see
 #ifndef GCC_CP_TYPE_UTILS_H
 #define GCC_CP_TYPE_UTILS_H
 
-/* Returns a pointer to the first tree within *TP that is directly matched by
-   PRED.  *TP may be a type or PARM_DECL and is incrementally decomposed toward
-   its type-specifier until a match is found.  NULL is returned if PRED does not
-   match any part of *TP.
+/* Returns the first tree within T that is directly matched by PRED.  T may be a
+   type or PARM_DECL and is incrementally decomposed toward its type-specifier
+   until a match is found.  NULL is returned if PRED does not match any
+   part of T.
 
-   This is primarily intended for detecting whether *TP uses `auto' or a concept
+   This is primarily intended for detecting whether T uses `auto' or a concept
    identifier.  Since either of these can only appear as a type-specifier for
    the declaration in question, only top-level qualifications are traversed;
    find_type_usage does not look through the whole type.  */
 
-inline tree *
-find_type_usage (tree *tp, bool (*pred) (const_tree))
+inline tree
+find_type_usage (tree t, bool (*pred) (const_tree))
 {
-  tree t = *tp;
   if (pred (t))
-    return tp;
+    return t;
 
   enum tree_code code = TREE_CODE (t);
 
@@ -43,13 +42,13 @@ find_type_usage (tree *tp, bool (*pred) (const_tree))
       || code == PARM_DECL || code == OFFSET_TYPE
       || code == FUNCTION_TYPE || code == METHOD_TYPE
       || code == ARRAY_TYPE)
-    return find_type_usage (&TREE_TYPE (t), pred);
+    return find_type_usage (TREE_TYPE (t), pred);
 
   if (TYPE_PTRMEMFUNC_P (t))
     return find_type_usage
-      (&TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (t)), pred);
+      (TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (t)), pred);
 
-  return NULL;
+  return NULL_TREE;
 }
 
 #endif // GCC_CP_TYPE_UTILS_H
diff --git a/gcc/testsuite/g++.dg/concepts/abbrev8.C b/gcc/testsuite/g++.dg/concepts/abbrev8.C
new file mode 100644
index 00000000000..ece9b0e44fd
--- /dev/null
+++ b/gcc/testsuite/g++.dg/concepts/abbrev8.C
@@ -0,0 +1,22 @@
+// PR c++/98990
+// { dg-do compile { target concepts } }
+
+int x;
+
+auto& f() { return x; }
+auto& f(auto) { return x; }
+
+using T1 = int&;
+using T1 = decltype(f('a'));
+
+int* y;
+
+template <class>
+struct S
+{
+  static auto** f() { return &y; }
+  static auto** f(auto) { return &y; }
+};
+
+using T2 = int**;
+using T2 = decltype(S<char>::f('a'));
-- 
2.30.0.452.gfb7fa4a1fd


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] c++: abbreviated function template return type rewriting [PR98990]
  2021-02-09 18:31 [PATCH] c++: abbreviated function template return type rewriting [PR98990] Patrick Palka
@ 2021-02-25 22:09 ` Patrick Palka
  2021-02-25 22:28   ` Jason Merrill
  0 siblings, 1 reply; 3+ messages in thread
From: Patrick Palka @ 2021-02-25 22:09 UTC (permalink / raw)
  To: Patrick Palka; +Cc: gcc-patches, jason

On Tue, 9 Feb 2021, Patrick Palka wrote:

> When an abbreviated function template has a complex placeholder return
> type such auto& or auto**, the level adjustment performed by
> splice_late_return_type directly replaces the 'auto' inside the original
> return type with the level-adjusted 'auto', but that breaks
> TYPE_CANONICAL caching.  Instead, we should rebuild the entire return
> type using the adjusted 'auto'.
> 
> This patch makes this happen by tsubsting the original return type with
> an argument vector that maps the original 'auto' to the adjusted 'auto'.
> In passing, this patch also reverts the misguided changes to
> find_type_usage in r10-6571 that made find_type_usage return a tree*
> instead of a tree so as to discourage this kind of in-place type
> modification.
> 
> It occurred to me that the constraint also needs to be rebuilt so that
> it refers to the adjusted 'auto', but this oversight doesn't seem to
> cause any issues at the moment due to how do_auto_deduction "manually"
> substitutes the 'auto' inside the constraint before performing
> satisfaction.  So this will instead be fixed as part of a broader rework
> of placeholder type constraint checking.
> 
> Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for
> trunk/10?

Ping.  Note that this patch will cause a merge conflict with the
uncommitted patch at
https://gcc.gnu.org/pipermail/gcc-patches/2021-February/565205.html,
so I plan to address the FIXME below as part of a new version of
that patch.

> 
> gcc/cp/ChangeLog:
> 
> 	PR c++/98990
> 	* pt.c (splice_late_return_type): Rebuild the entire return type
> 	if we have to adjust the level of the auto.  Use
> 	TEMPLATE_TYPE_LEVEL for brevity.
> 	(type_uses_auto): Adjust call to find_type_usage.
> 	* type-utils.h (find_type_usage): Revert r10-6571 change that
> 	made this function return a pointer to the auto node.
> 
> gcc/testsuite/ChangeLog:
> 
> 	PR c++/98990
> 	* g++.dg/concepts/abbrev8.C: New test.
> ---
>  gcc/cp/pt.c                             | 39 +++++++++++++------------
>  gcc/cp/type-utils.h                     | 23 +++++++--------
>  gcc/testsuite/g++.dg/concepts/abbrev8.C | 22 ++++++++++++++
>  3 files changed, 53 insertions(+), 31 deletions(-)
>  create mode 100644 gcc/testsuite/g++.dg/concepts/abbrev8.C
> 
> diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
> index c5b0a9292db..46cd322fbf4 100644
> --- a/gcc/cp/pt.c
> +++ b/gcc/cp/pt.c
> @@ -29601,22 +29601,25 @@ splice_late_return_type (tree type, tree late_return_type)
>        return late_return_type;
>      }
>  
> -  if (tree *auto_node = find_type_usage (&type, is_auto))
> -    {
> -      tree idx = get_template_parm_index (*auto_node);
> -      if (TEMPLATE_PARM_LEVEL (idx) <= processing_template_decl)
> -	{
> -	  /* In an abbreviated function template we didn't know we were dealing
> -	     with a function template when we saw the auto return type, so update
> -	     it to have the correct level.  */
> -	  tree new_auto = make_auto_1 (TYPE_IDENTIFIER (*auto_node), false);
> -	  PLACEHOLDER_TYPE_CONSTRAINTS (new_auto)
> -	    = PLACEHOLDER_TYPE_CONSTRAINTS (*auto_node);
> -	  TYPE_CANONICAL (new_auto) = canonical_type_parameter (new_auto);
> -	  new_auto = cp_build_qualified_type (new_auto, TYPE_QUALS (*auto_node));
> -	  *auto_node = new_auto;
> -	}
> -    }
> +  if (tree auto_node = find_type_usage (type, is_auto))
> +    if (TEMPLATE_TYPE_LEVEL (auto_node) <= processing_template_decl)
> +      {
> +	/* In an abbreviated function template we didn't know we were dealing
> +	   with a function template when we saw the auto return type, so rebuild
> +	   the return type using an auto with the correct level.  */
> +	tree new_auto = make_auto_1 (TYPE_IDENTIFIER (auto_node), false);
> +	tree auto_vec = make_tree_vec (1);
> +	TREE_VEC_ELT (auto_vec, 0) = new_auto;
> +	tree targs = add_outermost_template_args (current_template_args (),
> +						  auto_vec);
> +	/* FIXME: We should also rebuild the constraint to refer to the new
> +	   auto.  */
> +	PLACEHOLDER_TYPE_CONSTRAINTS (new_auto)
> +	  = PLACEHOLDER_TYPE_CONSTRAINTS (auto_node);
> +	TYPE_CANONICAL (new_auto) = canonical_type_parameter (new_auto);
> +	new_auto = cp_build_qualified_type (new_auto, TYPE_QUALS (auto_node));
> +	return tsubst (type, targs, tf_none, NULL_TREE);
> +      }
>    return type;
>  }
>  
> @@ -29661,10 +29664,8 @@ type_uses_auto (tree type)
>        else
>  	return NULL_TREE;
>      }
> -  else if (tree *tp = find_type_usage (&type, is_auto))
> -    return *tp;
>    else
> -    return NULL_TREE;
> +    return find_type_usage (type, is_auto);
>  }
>  
>  /* Report ill-formed occurrences of auto types in ARGUMENTS.  If
> diff --git a/gcc/cp/type-utils.h b/gcc/cp/type-utils.h
> index 5551e8f5ef1..138fed6c51e 100644
> --- a/gcc/cp/type-utils.h
> +++ b/gcc/cp/type-utils.h
> @@ -20,22 +20,21 @@ along with GCC; see the file COPYING3.  If not see
>  #ifndef GCC_CP_TYPE_UTILS_H
>  #define GCC_CP_TYPE_UTILS_H
>  
> -/* Returns a pointer to the first tree within *TP that is directly matched by
> -   PRED.  *TP may be a type or PARM_DECL and is incrementally decomposed toward
> -   its type-specifier until a match is found.  NULL is returned if PRED does not
> -   match any part of *TP.
> +/* Returns the first tree within T that is directly matched by PRED.  T may be a
> +   type or PARM_DECL and is incrementally decomposed toward its type-specifier
> +   until a match is found.  NULL is returned if PRED does not match any
> +   part of T.
>  
> -   This is primarily intended for detecting whether *TP uses `auto' or a concept
> +   This is primarily intended for detecting whether T uses `auto' or a concept
>     identifier.  Since either of these can only appear as a type-specifier for
>     the declaration in question, only top-level qualifications are traversed;
>     find_type_usage does not look through the whole type.  */
>  
> -inline tree *
> -find_type_usage (tree *tp, bool (*pred) (const_tree))
> +inline tree
> +find_type_usage (tree t, bool (*pred) (const_tree))
>  {
> -  tree t = *tp;
>    if (pred (t))
> -    return tp;
> +    return t;
>  
>    enum tree_code code = TREE_CODE (t);
>  
> @@ -43,13 +42,13 @@ find_type_usage (tree *tp, bool (*pred) (const_tree))
>        || code == PARM_DECL || code == OFFSET_TYPE
>        || code == FUNCTION_TYPE || code == METHOD_TYPE
>        || code == ARRAY_TYPE)
> -    return find_type_usage (&TREE_TYPE (t), pred);
> +    return find_type_usage (TREE_TYPE (t), pred);
>  
>    if (TYPE_PTRMEMFUNC_P (t))
>      return find_type_usage
> -      (&TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (t)), pred);
> +      (TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (t)), pred);
>  
> -  return NULL;
> +  return NULL_TREE;
>  }
>  
>  #endif // GCC_CP_TYPE_UTILS_H
> diff --git a/gcc/testsuite/g++.dg/concepts/abbrev8.C b/gcc/testsuite/g++.dg/concepts/abbrev8.C
> new file mode 100644
> index 00000000000..ece9b0e44fd
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/concepts/abbrev8.C
> @@ -0,0 +1,22 @@
> +// PR c++/98990
> +// { dg-do compile { target concepts } }
> +
> +int x;
> +
> +auto& f() { return x; }
> +auto& f(auto) { return x; }
> +
> +using T1 = int&;
> +using T1 = decltype(f('a'));
> +
> +int* y;
> +
> +template <class>
> +struct S
> +{
> +  static auto** f() { return &y; }
> +  static auto** f(auto) { return &y; }
> +};
> +
> +using T2 = int**;
> +using T2 = decltype(S<char>::f('a'));
> -- 
> 2.30.0.452.gfb7fa4a1fd
> 
> 


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] c++: abbreviated function template return type rewriting [PR98990]
  2021-02-25 22:09 ` Patrick Palka
@ 2021-02-25 22:28   ` Jason Merrill
  0 siblings, 0 replies; 3+ messages in thread
From: Jason Merrill @ 2021-02-25 22:28 UTC (permalink / raw)
  To: Patrick Palka; +Cc: gcc-patches

On 2/25/21 5:09 PM, Patrick Palka wrote:
> On Tue, 9 Feb 2021, Patrick Palka wrote:
> 
>> When an abbreviated function template has a complex placeholder return
>> type such auto& or auto**, the level adjustment performed by
>> splice_late_return_type directly replaces the 'auto' inside the original
>> return type with the level-adjusted 'auto', but that breaks
>> TYPE_CANONICAL caching.  Instead, we should rebuild the entire return
>> type using the adjusted 'auto'.
>>
>> This patch makes this happen by tsubsting the original return type with
>> an argument vector that maps the original 'auto' to the adjusted 'auto'.
>> In passing, this patch also reverts the misguided changes to
>> find_type_usage in r10-6571 that made find_type_usage return a tree*
>> instead of a tree so as to discourage this kind of in-place type
>> modification.
>>
>> It occurred to me that the constraint also needs to be rebuilt so that
>> it refers to the adjusted 'auto', but this oversight doesn't seem to
>> cause any issues at the moment due to how do_auto_deduction "manually"
>> substitutes the 'auto' inside the constraint before performing
>> satisfaction.  So this will instead be fixed as part of a broader rework
>> of placeholder type constraint checking.
>>
>> Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for
>> trunk/10?
> 
> Ping.  Note that this patch will cause a merge conflict with the
> uncommitted patch at
> https://gcc.gnu.org/pipermail/gcc-patches/2021-February/565205.html,
> so I plan to address the FIXME below as part of a new version of
> that patch.
> 
>>
>> gcc/cp/ChangeLog:
>>
>> 	PR c++/98990
>> 	* pt.c (splice_late_return_type): Rebuild the entire return type
>> 	if we have to adjust the level of the auto.  Use
>> 	TEMPLATE_TYPE_LEVEL for brevity.
>> 	(type_uses_auto): Adjust call to find_type_usage.
>> 	* type-utils.h (find_type_usage): Revert r10-6571 change that
>> 	made this function return a pointer to the auto node.
>>
>> gcc/testsuite/ChangeLog:
>>
>> 	PR c++/98990
>> 	* g++.dg/concepts/abbrev8.C: New test.
>> ---
>>   gcc/cp/pt.c                             | 39 +++++++++++++------------
>>   gcc/cp/type-utils.h                     | 23 +++++++--------
>>   gcc/testsuite/g++.dg/concepts/abbrev8.C | 22 ++++++++++++++
>>   3 files changed, 53 insertions(+), 31 deletions(-)
>>   create mode 100644 gcc/testsuite/g++.dg/concepts/abbrev8.C
>>
>> diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
>> index c5b0a9292db..46cd322fbf4 100644
>> --- a/gcc/cp/pt.c
>> +++ b/gcc/cp/pt.c
>> @@ -29601,22 +29601,25 @@ splice_late_return_type (tree type, tree late_return_type)
>>         return late_return_type;
>>       }
>>   
>> -  if (tree *auto_node = find_type_usage (&type, is_auto))
>> -    {
>> -      tree idx = get_template_parm_index (*auto_node);
>> -      if (TEMPLATE_PARM_LEVEL (idx) <= processing_template_decl)
>> -	{
>> -	  /* In an abbreviated function template we didn't know we were dealing
>> -	     with a function template when we saw the auto return type, so update
>> -	     it to have the correct level.  */
>> -	  tree new_auto = make_auto_1 (TYPE_IDENTIFIER (*auto_node), false);
>> -	  PLACEHOLDER_TYPE_CONSTRAINTS (new_auto)
>> -	    = PLACEHOLDER_TYPE_CONSTRAINTS (*auto_node);
>> -	  TYPE_CANONICAL (new_auto) = canonical_type_parameter (new_auto);
>> -	  new_auto = cp_build_qualified_type (new_auto, TYPE_QUALS (*auto_node));
>> -	  *auto_node = new_auto;
>> -	}
>> -    }
>> +  if (tree auto_node = find_type_usage (type, is_auto))
>> +    if (TEMPLATE_TYPE_LEVEL (auto_node) <= processing_template_decl)
>> +      {
>> +	/* In an abbreviated function template we didn't know we were dealing
>> +	   with a function template when we saw the auto return type, so rebuild
>> +	   the return type using an auto with the correct level.  */
>> +	tree new_auto = make_auto_1 (TYPE_IDENTIFIER (auto_node), false);
>> +	tree auto_vec = make_tree_vec (1);
>> +	TREE_VEC_ELT (auto_vec, 0) = new_auto;
>> +	tree targs = add_outermost_template_args (current_template_args (),
>> +						  auto_vec);
>> +	/* FIXME: We should also rebuild the constraint to refer to the new
>> +	   auto.  */
>> +	PLACEHOLDER_TYPE_CONSTRAINTS (new_auto)
>> +	  = PLACEHOLDER_TYPE_CONSTRAINTS (auto_node);
>> +	TYPE_CANONICAL (new_auto) = canonical_type_parameter (new_auto);

For the FIXME it would be nice to adjust 
make_constrained_auto/_placeholder_type to handle this for you.

>> +	new_auto = cp_build_qualified_type (new_auto, TYPE_QUALS (auto_node));

I'd expect this to be taken care of by the tsubst now.  OK without this 
line.

>> +	return tsubst (type, targs, tf_none, NULL_TREE);
>> +      }
>>     return type;
>>   }
>>   
>> @@ -29661,10 +29664,8 @@ type_uses_auto (tree type)
>>         else
>>   	return NULL_TREE;
>>       }
>> -  else if (tree *tp = find_type_usage (&type, is_auto))
>> -    return *tp;
>>     else
>> -    return NULL_TREE;
>> +    return find_type_usage (type, is_auto);
>>   }
>>   
>>   /* Report ill-formed occurrences of auto types in ARGUMENTS.  If
>> diff --git a/gcc/cp/type-utils.h b/gcc/cp/type-utils.h
>> index 5551e8f5ef1..138fed6c51e 100644
>> --- a/gcc/cp/type-utils.h
>> +++ b/gcc/cp/type-utils.h
>> @@ -20,22 +20,21 @@ along with GCC; see the file COPYING3.  If not see
>>   #ifndef GCC_CP_TYPE_UTILS_H
>>   #define GCC_CP_TYPE_UTILS_H
>>   
>> -/* Returns a pointer to the first tree within *TP that is directly matched by
>> -   PRED.  *TP may be a type or PARM_DECL and is incrementally decomposed toward
>> -   its type-specifier until a match is found.  NULL is returned if PRED does not
>> -   match any part of *TP.
>> +/* Returns the first tree within T that is directly matched by PRED.  T may be a
>> +   type or PARM_DECL and is incrementally decomposed toward its type-specifier
>> +   until a match is found.  NULL is returned if PRED does not match any
>> +   part of T.
>>   
>> -   This is primarily intended for detecting whether *TP uses `auto' or a concept
>> +   This is primarily intended for detecting whether T uses `auto' or a concept
>>      identifier.  Since either of these can only appear as a type-specifier for
>>      the declaration in question, only top-level qualifications are traversed;
>>      find_type_usage does not look through the whole type.  */
>>   
>> -inline tree *
>> -find_type_usage (tree *tp, bool (*pred) (const_tree))
>> +inline tree
>> +find_type_usage (tree t, bool (*pred) (const_tree))
>>   {
>> -  tree t = *tp;
>>     if (pred (t))
>> -    return tp;
>> +    return t;
>>   
>>     enum tree_code code = TREE_CODE (t);
>>   
>> @@ -43,13 +42,13 @@ find_type_usage (tree *tp, bool (*pred) (const_tree))
>>         || code == PARM_DECL || code == OFFSET_TYPE
>>         || code == FUNCTION_TYPE || code == METHOD_TYPE
>>         || code == ARRAY_TYPE)
>> -    return find_type_usage (&TREE_TYPE (t), pred);
>> +    return find_type_usage (TREE_TYPE (t), pred);
>>   
>>     if (TYPE_PTRMEMFUNC_P (t))
>>       return find_type_usage
>> -      (&TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (t)), pred);
>> +      (TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (t)), pred);
>>   
>> -  return NULL;
>> +  return NULL_TREE;
>>   }
>>   
>>   #endif // GCC_CP_TYPE_UTILS_H
>> diff --git a/gcc/testsuite/g++.dg/concepts/abbrev8.C b/gcc/testsuite/g++.dg/concepts/abbrev8.C
>> new file mode 100644
>> index 00000000000..ece9b0e44fd
>> --- /dev/null
>> +++ b/gcc/testsuite/g++.dg/concepts/abbrev8.C
>> @@ -0,0 +1,22 @@
>> +// PR c++/98990
>> +// { dg-do compile { target concepts } }
>> +
>> +int x;
>> +
>> +auto& f() { return x; }
>> +auto& f(auto) { return x; }
>> +
>> +using T1 = int&;
>> +using T1 = decltype(f('a'));
>> +
>> +int* y;
>> +
>> +template <class>
>> +struct S
>> +{
>> +  static auto** f() { return &y; }
>> +  static auto** f(auto) { return &y; }
>> +};
>> +
>> +using T2 = int**;
>> +using T2 = decltype(S<char>::f('a'));
>> -- 
>> 2.30.0.452.gfb7fa4a1fd
>>
>>
> 


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2021-02-25 22:29 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-02-09 18:31 [PATCH] c++: abbreviated function template return type rewriting [PR98990] Patrick Palka
2021-02-25 22:09 ` Patrick Palka
2021-02-25 22:28   ` Jason Merrill

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).