Tested x86_64-pc-linux-gnu, applying to trunk.

-- 8< --

Here when substituting BITS into poly_table convert_template_argument adds
an IMPLICIT_CONV_EXPR to represent the conversion to the alias template
parameter.  In r16-4115 I extended that to value-dependent arguments as well
as type-dependent, in case the conversion turns out to be narrowing.
tsubst_expr needs the same change so maybe_update_decl_type doesn't
replace the IMPLICIT_CONV_EXPR with a NOP_EXPR.

The do_auto_deduction change is to avoid a regression in nontype-auto21.C
when the first test is changed from uses_template_parms (as it was in
convert_template_argument) to dependent_type_p; this mattered because we
were failing to resolve the auto return type before deducing the auto
non-type parameter type from helper<token>::c.  Many other places that call
resolve_nondeduced_context similarly then call mark_single_function.

        PR c++/122171
        PR c++/112632

gcc/cp/ChangeLog:

        * pt.cc (dependent_implict_conv_p): Split out...
        (convert_template_argument): ...from here.
        (tsubst_expr) [IMPLICIT_CONV_EXPR]: Use it.
        (do_auto_deduction): Call mark_single_function.

gcc/testsuite/ChangeLog:

        * g++.dg/cpp0x/alias-decl-conv1.C: New test.
---
 gcc/cp/pt.cc                                  | 35 ++++++++++++++-----
 gcc/testsuite/g++.dg/cpp0x/alias-decl-conv1.C | 17 +++++++++
 2 files changed, 43 insertions(+), 9 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/cpp0x/alias-decl-conv1.C

diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index 4dc8f980d0d..3a59714d588 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -8646,6 +8646,19 @@ maybe_convert_nontype_argument (tree type, tree arg, 
bool force)
   return arg;
 }
 
+/* True if we need an IMPLICIT_CONV_EXPR for converting EXPR to TYPE, possibly
+   in a FORCED context (i.e. alias or concept).  */
+
+static bool
+dependent_implict_conv_p (tree type, tree expr, bool forced)
+{
+  return (dependent_type_p (type) || type_dependent_expression_p (expr)
+         || (forced
+             && !(same_type_ignoring_top_level_qualifiers_p
+                  (TREE_TYPE (expr), type))
+             && value_dependent_expression_p (expr)));
+}
+
 /* Convert the indicated template ARG as necessary to match the
    indicated template PARM.  Returns the converted ARG, or
    error_mark_node if the conversion was unsuccessful.  Error and
@@ -8926,12 +8939,7 @@ convert_template_argument (tree parm,
          && same_type_p (TREE_TYPE (orig_arg), t))
        orig_arg = TREE_OPERAND (orig_arg, 0);
 
-      if (!uses_template_parms (t)
-         && !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)))
+      if (!dependent_implict_conv_p (t, orig_arg, force_conv))
        /* 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
@@ -21031,7 +21039,8 @@ tsubst_expr (tree t, tree args, tsubst_flags_t 
complain, tree in_decl)
        if (type == error_mark_node)
          RETURN (error_mark_node);
        tree expr = RECUR (TREE_OPERAND (t, 0));
-       if (dependent_type_p (type) || type_dependent_expression_p (expr))
+       if (dependent_implict_conv_p (type, expr,
+                                     IMPLICIT_CONV_EXPR_FORCED (t)))
          {
            retval = copy_node (t);
            TREE_TYPE (retval) = type;
@@ -32147,10 +32156,18 @@ do_auto_deduction (tree type, tree init, tree 
auto_node,
         initializer_list.  */
       if (CONSTRUCTOR_ELTS (init))
        for (constructor_elt &elt : CONSTRUCTOR_ELTS (init))
-         elt.value = resolve_nondeduced_context (elt.value, complain);
+         {
+           elt.value = resolve_nondeduced_context (elt.value, complain);
+           if (!mark_single_function (elt.value, complain))
+             return error_mark_node;
+         }
     }
   else if (init)
-    init = resolve_nondeduced_context (init, complain);
+    {
+      init = resolve_nondeduced_context (init, complain);
+      if (!mark_single_function (init, complain))
+       return error_mark_node;
+    }
 
   /* In C++23, we must deduce the type to int&& for code like
        decltype(auto) f(int&& x) { return (x); }
diff --git a/gcc/testsuite/g++.dg/cpp0x/alias-decl-conv1.C 
b/gcc/testsuite/g++.dg/cpp0x/alias-decl-conv1.C
new file mode 100644
index 00000000000..9fb18a78fd8
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/alias-decl-conv1.C
@@ -0,0 +1,17 @@
+// PR c++/122171
+// { dg-do compile { target c++11 } }
+
+constexpr unsigned int poly_size(unsigned int bits) {
+  return 1;
+}
+
+template <unsigned int Deg>
+using poly_table = char[poly_size(Deg)];
+
+template <int BITS>
+struct FingerprintTable {
+  static const poly_table<BITS> table;
+};
+
+template <int BITS>
+const poly_table<BITS> FingerprintTable<BITS>::table = {};

base-commit: 89130a50108077e81a11a60007de6830c9f23b34
-- 
2.51.1

Reply via email to