]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
PR c++/92150 - partial specialization with class NTTP.
authorJason Merrill <jason@redhat.com>
Fri, 13 Dec 2019 05:09:57 +0000 (00:09 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Fri, 13 Dec 2019 05:09:57 +0000 (00:09 -0500)
Here unify was getting confused by the VIEW_CONVERT_EXPR we add in
finish_id_expression_1 to make class NTTP const when they're used in an
expression.

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

* pt.c (unify): Handle VIEW_CONVERT_EXPR.

From-SVN: r279332

gcc/cp/ChangeLog
gcc/cp/pt.c
gcc/testsuite/g++.dg/cpp2a/nontype-class24.C [new file with mode: 0644]

index ae4ba4a372a2ec27173ab96d90b728542860dd6d..19d70a3297889025cf9553847d7287c51b9b6040 100644 (file)
@@ -1,3 +1,8 @@
+2019-11-06  Jason Merrill  <jason@redhat.com>
+
+       PR c++/92150 - partial specialization with class NTTP.
+       * pt.c (unify): Handle VIEW_CONVERT_EXPR.
+
 2019-11-20  Jakub Jelinek  <jakub@redhat.com>
 
        PR c++/90767
index 48d8dbb6ad2d80ae6b07760becbefb90ed60ce7c..aa78ac980b3cfa58596a2f79372ed67069165489 100644 (file)
@@ -22045,8 +22045,9 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict,
   /* I don't think this will do the right thing with respect to types.
      But the only case I've seen it in so far has been array bounds, where
      signedness is the only information lost, and I think that will be
-     okay.  */
-  while (CONVERT_EXPR_P (parm))
+     okay.  VIEW_CONVERT_EXPR can appear with class NTTP, thanks to
+     finish_id_expression_1, and are also OK.  */
+  while (CONVERT_EXPR_P (parm) || TREE_CODE (parm) == VIEW_CONVERT_EXPR)
     parm = TREE_OPERAND (parm, 0);
 
   if (arg == error_mark_node)
diff --git a/gcc/testsuite/g++.dg/cpp2a/nontype-class24.C b/gcc/testsuite/g++.dg/cpp2a/nontype-class24.C
new file mode 100644 (file)
index 0000000..aa96de3
--- /dev/null
@@ -0,0 +1,19 @@
+// PR c++/92150
+// { dg-do compile { target c++2a } }
+
+struct X {
+  int value;
+  // auto operator==(const X&) = default;
+};
+
+template<typename T, X N>
+struct b;
+
+template<typename T>
+inline constexpr bool is_b = false;
+
+template<typename T, X N>
+inline constexpr bool is_b<b<T, N>> = true;
+
+using my_b = b<int, X{1}>;
+static_assert(is_b<my_b>);