On Mon, 27 Jan 2025, Patrick Palka wrote:

> Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look
> OK for trunk/14?
> 
> -- >8 --
> 
> We recently started using the lang_decl_fn::context field to track
> inheritedness of a deduction guide (for C++23 inherited CTAD).  This
> new overloading of the field accidentally made DECL_FRIEND_CONTEXT
> return non-NULL for inherited guides, which breaks the below testcase
> overload resolution containing an inherited guide.
> 
> This patch fixes this by refining DECL_FRIEND_CONTEXT to return NULL
> for deduction guides.
> 
>       PR c++/117855
> 
> gcc/cp/ChangeLog:
> 
>       * cp-tree.h (DECL_FRIEND_CONTEXT): Refine to exclude deduction
>       guides.
> 
> gcc/testsuite/ChangeLog:
> 
>       * g++.dg/cpp23/class-deduction-inherited7.C: New test.
> ---
>  gcc/cp/cp-tree.h                                     |  3 ++-
>  .../g++.dg/cpp23/class-deduction-inherited7.C        | 12 ++++++++++++
>  2 files changed, 14 insertions(+), 1 deletion(-)
>  create mode 100644 gcc/testsuite/g++.dg/cpp23/class-deduction-inherited7.C
> 
> diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
> index c9128bd3e7b..dc527380921 100644
> --- a/gcc/cp/cp-tree.h
> +++ b/gcc/cp/cp-tree.h
> @@ -3631,7 +3631,8 @@ struct GTY(()) lang_decl {
>     the DECL_FRIEND_CONTEXT for `f' will be `S'.  */
>  #define DECL_FRIEND_CONTEXT(NODE)                            \
>    ((DECL_DECLARES_FUNCTION_P (NODE) && !DECL_VIRTUAL_P (NODE)        \
> -    && !DECL_CONSTRUCTOR_P (NODE))                           \
> +    && !DECL_CONSTRUCTOR_P (NODE)                            \
> +    && (cxx_dialect < cxx23 || !deduction_guide_p (NODE)))   \

N.B. I decided to check cxx_dialect here since deduction_guide_p seems
relatively expensive to call?  In another version of this patch I made
us track dguide-ness via a dedicated bit flag instead of the DECL_NAME
comparison to make the predicate essentially free (and potentially also
more robust) but I eventually shelved that as more stage 1 material.

>     ? LANG_DECL_FN_CHECK (NODE)->context                              \
>     : NULL_TREE)
>  
> diff --git a/gcc/testsuite/g++.dg/cpp23/class-deduction-inherited7.C 
> b/gcc/testsuite/g++.dg/cpp23/class-deduction-inherited7.C
> new file mode 100644
> index 00000000000..b1d5e89ad02
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/cpp23/class-deduction-inherited7.C
> @@ -0,0 +1,12 @@
> +// PR c++/117855
> +// { dg-do compile { target c++20 } }
> +
> +template <typename T, int _Extent = -1> struct span { span(T&&);};
> +template <typename T> span(T &&) -> span<T>;
> +template <typename et, int e = -1>
> +struct this_span : span<et, e> {
> +  using span<et, e>::span;
> +};
> +template <typename T> this_span(T &&) -> this_span<T>;
> +int vec;
> +this_span a = vec;
> -- 
> 2.48.1.91.g5f8f7081f7
> 
> 

Reply via email to