diff options
author | Jason Merrill <jason@redhat.com> | 2021-02-25 16:47:53 -0500 |
---|---|---|
committer | Jason Merrill <jason@redhat.com> | 2021-02-25 22:57:48 -0500 |
commit | 7c657339d6a4a671b4cd8bc62ba4e0df6bfc7c72 (patch) | |
tree | 12e25384d7e0d1bab3e76732dfa2f27b0e03eadc /gcc | |
parent | 0159535adb0e7400f2c6922f14a7602f6b90cf69 (diff) | |
download | gcc-7c657339d6a4a671b4cd8bc62ba4e0df6bfc7c72.zip gcc-7c657339d6a4a671b4cd8bc62ba4e0df6bfc7c72.tar.gz gcc-7c657339d6a4a671b4cd8bc62ba4e0df6bfc7c72.tar.bz2 |
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.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/pt.c | 27 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp2a/nontype-class-defarg1.C | 6 |
2 files changed, 24 insertions, 9 deletions
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 <auto> struct a {}; +template <int i, a <i> s = a <i> {}> using b = a <s>; +template <int i> constexpr auto g (const b <i> &) { return true; }; |