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