aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathan Sidwell <nathan@acm.org>2020-02-27 10:50:36 -0800
committerNathan Sidwell <nathan@acm.org>2020-02-27 10:50:36 -0800
commit9d2d283367a407c1ba9ecdb8590f9295828e25f8 (patch)
tree670766297b077469d190cbf4fad93b2c4191d4c2
parentba49e9eb18730cc71e5ffc302092f87ef6821f24 (diff)
downloadgcc-9d2d283367a407c1ba9ecdb8590f9295828e25f8.zip
gcc-9d2d283367a407c1ba9ecdb8590f9295828e25f8.tar.gz
gcc-9d2d283367a407c1ba9ecdb8590f9295828e25f8.tar.bz2
Compare ARGUMENT_PACKS [pr93933]
This implements Jason's suggested approach: 'I'd think that the bug is that we're treating them as types in the first place; they aren't types, so they shouldn't reach comptypes. I'd lean toward adding an assert to that effect and fixing the caller to use e.g. template_args_equal.' PR c++/93933 * pt.c (template_args_equal): Pass ARGUMENT_PACKS through to cp_tree_equal. * tree.c (cp_tree_equal): Compare ARGUMENT_PACKS here, * typeck.c (comptypes): Assert we don't get any argument packs.
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/pt.c21
-rw-r--r--gcc/cp/tree.c17
-rw-r--r--gcc/cp/typeck.c4
-rw-r--r--gcc/testsuite/g++.dg/concepts/pr93933.C31
5 files changed, 59 insertions, 20 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 5e9eeec..22fe803 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,11 @@
2020-02-27 Nathan Sidwell <nathan@acm.org>
+ PR c++/93933
+ * pt.c (template_args_equal): Pass ARGUMENT_PACKS through to
+ cp_tree_equal.
+ * tree.c (cp_tree_equal): Compare ARGUMENT_PACKS here,
+ * typeck.c (comptypes): Assert we don't get any argument packs.
+
* class.c (adjust_clone_args): Correct arg-checking assert.
* typeck.c (comptypes): Assert not nulls.
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 6c9abb8..622c70b 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -8999,25 +8999,8 @@ template_args_equal (tree ot, tree nt, bool partial_order /* = false */)
PACK_EXPANSION_PATTERN (nt))
&& template_args_equal (PACK_EXPANSION_EXTRA_ARGS (ot),
PACK_EXPANSION_EXTRA_ARGS (nt)));
- else if (ARGUMENT_PACK_P (ot))
- {
- int i, len;
- tree opack, npack;
-
- if (!ARGUMENT_PACK_P (nt))
- return 0;
-
- opack = ARGUMENT_PACK_ARGS (ot);
- npack = ARGUMENT_PACK_ARGS (nt);
- len = TREE_VEC_LENGTH (opack);
- if (TREE_VEC_LENGTH (npack) != len)
- return 0;
- for (i = 0; i < len; ++i)
- if (!template_args_equal (TREE_VEC_ELT (opack, i),
- TREE_VEC_ELT (npack, i)))
- return 0;
- return 1;
- }
+ else if (ARGUMENT_PACK_P (ot) || ARGUMENT_PACK_P (nt))
+ return cp_tree_equal (ot, nt);
else if (ot && TREE_CODE (ot) == ARGUMENT_PACK_SELECT)
gcc_unreachable ();
else if (TYPE_P (nt))
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index 72b3a72..3fc6287 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -3857,12 +3857,27 @@ cp_tree_equal (tree t1, tree t2)
DEFERRED_NOEXCEPT_PATTERN (t2))
&& comp_template_args (DEFERRED_NOEXCEPT_ARGS (t1),
DEFERRED_NOEXCEPT_ARGS (t2)));
- break;
case LAMBDA_EXPR:
/* Two lambda-expressions are never considered equivalent. */
return false;
+ case TYPE_ARGUMENT_PACK:
+ case NONTYPE_ARGUMENT_PACK:
+ {
+ tree p1 = ARGUMENT_PACK_ARGS (t1);
+ tree p2 = ARGUMENT_PACK_ARGS (t2);
+ int len = TREE_VEC_LENGTH (p1);
+ if (TREE_VEC_LENGTH (p2) != len)
+ return false;
+
+ for (int ix = 0; ix != len; ix++)
+ if (!template_args_equal (TREE_VEC_ELT (p1, ix),
+ TREE_VEC_ELT (p2, ix)))
+ return false;
+ return true;
+ }
+
default:
break;
}
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 42d0b47..2a3243f 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -1485,6 +1485,10 @@ comptypes (tree t1, tree t2, int strict)
{
gcc_checking_assert (t1 && t2);
+ /* TYPE_ARGUMENT_PACKS are not really types. */
+ gcc_checking_assert (TREE_CODE (t1) != TYPE_ARGUMENT_PACK
+ && TREE_CODE (t2) != TYPE_ARGUMENT_PACK);
+
if (strict == COMPARE_STRICT && comparing_specializations
&& (t1 != TYPE_CANONICAL (t1) || t2 != TYPE_CANONICAL (t2)))
/* If comparing_specializations, treat dependent aliases as distinct. */
diff --git a/gcc/testsuite/g++.dg/concepts/pr93933.C b/gcc/testsuite/g++.dg/concepts/pr93933.C
new file mode 100644
index 0000000..b4f2c36
--- /dev/null
+++ b/gcc/testsuite/g++.dg/concepts/pr93933.C
@@ -0,0 +1,31 @@
+// { dg-do compile { target c++17 } }
+// { dg-options "-fconcepts" }
+
+// distilled from <concepts>, via header units
+
+template<typename _ArgTypes>
+struct is_invocable;
+
+template<typename... _Args>
+concept invocable = is_invocable<_Args...>::value;
+
+template<typename _Is>
+requires invocable<_Is>
+class BUG;
+
+template<typename _Is>
+requires invocable<_Is>
+class BUG {}; // { dg-bogus "different constraints" }
+
+template<int> struct is_invocable_NT;
+
+template<int... Ints>
+concept invocable_NT = is_invocable_NT<Ints...>::value;
+
+template<int _Is>
+requires invocable_NT<_Is>
+class BUG_NT;
+
+template<int _Is>
+requires invocable_NT<_Is>
+class BUG_NT {};