From: Jason Merrill Date: Tue, 2 Dec 2025 12:48:39 +0000 (+0530) Subject: c++: alias template parm conv and redecl [PR122171] X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=d58f2e5453c6d7dc93315fb324f55607241c91f9;p=thirdparty%2Fgcc.git c++: alias template parm conv and redecl [PR122171] 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::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. --- 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 +using poly_table = char[poly_size(Deg)]; + +template +struct FingerprintTable { + static const poly_table table; +}; + +template +const poly_table FingerprintTable::table = {};