https://gcc.gnu.org/g:5ee5a05da06078975a933be849431eee1d4c6989

commit r16-4211-g5ee5a05da06078975a933be849431eee1d4c6989
Author: Jason Merrill <[email protected]>
Date:   Fri Oct 3 18:10:36 2025 +0100

    c++: concepts and conversions, take 2 [PR122127]
    
    My r16-4115 changed convert_template_argument (when called from
    instantiate_alias_template) to take the maybe_convert_nontype_argument path
    rather than convert_nontype_argument for this testcase.  This meant not
    folding the use of the by-ref capture in the template argument to constant
    1.  When we come back to convert_template_argument again when substituting
    into resize<_Np> we strip the IMPLICIT_CONV_EXPR (since the types are the
    same) and take the convert_nontype_argument path, but at this point we've
    pushed into the alias template context and trying to fold away the capture
    fails because current_lambda_expr() is now null.
    
    Taking the convert_nontype_argument path in the same-type case where we
    would later strip an IMPLICIT_CONV_EXPR fixes the problem.  Note that
    maybe_convert_nontype_argument already shares the same-type check with the
    stripping, but that isn't enough; it still doesn't fold away the capture
    proxy.
    
            PR c++/122127
            PR c++/112632
    
    gcc/cp/ChangeLog:
    
            * pt.cc (convert_template_argument): Don't add redundant
            IMPLICIT_CONV_EXPR.
    
    gcc/testsuite/ChangeLog:
    
            * g++.dg/cpp0x/lambda/lambda-template18.C: New test.

Diff:
---
 gcc/cp/pt.cc                                          |  7 +++++--
 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-template18.C | 11 +++++++++++
 2 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index bd60d515653b..9b32049e71be 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -8928,8 +8928,11 @@ convert_template_argument (tree parm,
        orig_arg = TREE_OPERAND (orig_arg, 0);
 
       if (!uses_template_parms (t)
-         && !(force_conv ? uses_template_parms (orig_arg)
-              : type_dependent_expression_p (orig_arg)))
+         && !type_dependent_expression_p (orig_arg)
+         && !(force_conv
+              && !(same_type_ignoring_top_level_qualifiers_p
+                   (TREE_TYPE (orig_arg), t))
+              && value_dependent_expression_p (orig_arg)))
        /* We used to call digest_init here.  However, digest_init
           will report errors, which we don't want when complain
           is zero.  More importantly, digest_init will try too
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-template18.C 
b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-template18.C
new file mode 100644
index 000000000000..e5e6e6a875b9
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-template18.C
@@ -0,0 +1,11 @@
+// PR c++/122127
+// { dg-do compile { target c++11 } }
+
+template <int> struct resize;
+template <int _Np> using resize_t = resize<_Np>;
+template <class _Ap> struct basic_mask {
+  void _M_chunk() {
+    constexpr int __rem = 1;
+    [&] { resize_t<__rem>(); }();
+  }
+};

Reply via email to