From 7c657339d6a4a671b4cd8bc62ba4e0df6bfc7c72 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Thu, 25 Feb 2021 16:47:53 -0500 Subject: [PATCH] c++: Fix class NTTP constness handling [PR98810] Here, when substituting still-dependent args into an alias template, we see a non-const type because the default argument is non-const, and is not a template parm object because it's still dependent. gcc/cp/ChangeLog: PR c++/98810 * pt.c (tsubst_copy) [VIEW_CONVERT_EXPR]: Add const to a class non-type template argument that needs it. gcc/testsuite/ChangeLog: PR c++/98810 * g++.dg/cpp2a/nontype-class-defarg1.C: New test. --- gcc/cp/pt.c | 27 ++++++++++++++-------- gcc/testsuite/g++.dg/cpp2a/nontype-class-defarg1.C | 6 +++++ 2 files changed, 24 insertions(+), 9 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp2a/nontype-class-defarg1.C diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 51abc86..6a2c4f3 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -16826,18 +16826,27 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl) { /* Wrapper to make a C++20 template parameter object const. */ op = tsubst_copy (op, args, complain, in_decl); - if (TREE_CODE (op) == TEMPLATE_PARM_INDEX) + if (!CP_TYPE_CONST_P (TREE_TYPE (op))) { + /* The template argument is not const, presumably because + it is still dependent, and so not the const template parm + object. */ tree type = tsubst (TREE_TYPE (t), args, complain, in_decl); - return build1 (code, type, op); - } - else - { - gcc_assert (CP_TYPE_CONST_P (TREE_TYPE (op)) - || (TREE_CODE (op) == IMPLICIT_CONV_EXPR - && IMPLICIT_CONV_EXPR_NONTYPE_ARG (op))); - return op; + gcc_checking_assert (same_type_ignoring_top_level_qualifiers_p + (type, TREE_TYPE (op))); + if (TREE_CODE (op) == CONSTRUCTOR + || TREE_CODE (op) == IMPLICIT_CONV_EXPR) + { + /* Don't add a wrapper to these. */ + op = copy_node (op); + TREE_TYPE (op) = type; + } + else + /* Do add a wrapper otherwise (in particular, if op is + another TEMPLATE_PARM_INDEX). */ + op = build1 (code, type, op); } + return op; } /* force_paren_expr can also create a VIEW_CONVERT_EXPR. */ else if (code == VIEW_CONVERT_EXPR && REF_PARENTHESIZED_P (t)) diff --git a/gcc/testsuite/g++.dg/cpp2a/nontype-class-defarg1.C b/gcc/testsuite/g++.dg/cpp2a/nontype-class-defarg1.C new file mode 100644 index 0000000..85e50ff --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/nontype-class-defarg1.C @@ -0,0 +1,6 @@ +// PR c++/98810 +// { dg-do compile { target c++20 } } + +template struct a {}; +template s = a {}> using b = a ; +template constexpr auto g (const b &) { return true; }; -- 2.7.4