public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc/devel/autopar_devel] PR c++/93286 - ICE with __is_constructible and variadic template.
@ 2020-08-22 21:17 Giuliano Belinassi
0 siblings, 0 replies; only message in thread
From: Giuliano Belinassi @ 2020-08-22 21:17 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:b0b21b3fd331a295622d9ef3579a0df2f88bd1da
commit b0b21b3fd331a295622d9ef3579a0df2f88bd1da
Author: Jason Merrill <jason@redhat.com>
Date: Fri May 15 14:06:48 2020 -0400
PR c++/93286 - ICE with __is_constructible and variadic template.
My GCC 10 patch for 93286 fixed the missing piece in tsubst's handling of
lists vs. that in tsubst_copy_and_build, but it would be better to share the
code between them.
gcc/cp/ChangeLog
2020-05-15 Jason Merrill <jason@redhat.com>
PR c++/93286 - ICE with __is_constructible and variadic template.
* pt.c (tsubst_tree_list): New.
(tsubst, tsubst_copy_and_build): Use it.
* decl2.c (is_late_template_attribute): Handle error_mark_node args.
Diff:
---
gcc/cp/ChangeLog | 7 ++
gcc/cp/cp-tree.h | 2 +-
gcc/cp/decl2.c | 3 +
gcc/cp/pt.c | 272 ++++++++++++++++++-------------------------------------
4 files changed, 101 insertions(+), 183 deletions(-)
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 37705f9f93d..732be07c9c0 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,10 @@
+2020-05-15 Jason Merrill <jason@redhat.com>
+
+ PR c++/93286 - ICE with __is_constructible and variadic template.
+ * pt.c (tsubst_tree_list): New.
+ (tsubst, tsubst_copy_and_build): Use it.
+ * decl2.c (is_late_template_attribute): Handle error_mark_node args.
+
2020-05-15 Nathan Sidwell <nathan@acm.org>
* pt.c (template_args_equal): Fix thinkos in previous 'cleanup'.
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 827b03dd5d5..3f7ded4798f 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -6953,7 +6953,7 @@ extern tree tsubst_default_argument (tree, int, tree, tree,
tsubst_flags_t);
extern tree tsubst (tree, tree, tsubst_flags_t, tree);
extern tree tsubst_copy_and_build (tree, tree, tsubst_flags_t,
- tree, bool, bool);
+ tree, bool = false, bool = false);
extern tree tsubst_expr (tree, tree, tsubst_flags_t,
tree, bool);
extern tree tsubst_pack_expansion (tree, tree, tsubst_flags_t, tree);
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index 4767d53adef..449c86c66c9 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -1173,6 +1173,9 @@ is_late_template_attribute (tree attr, tree decl)
&& is_attribute_p ("omp declare simd", name))
return true;
+ if (args == error_mark_node)
+ return false;
+
/* An attribute pack is clearly dependent. */
if (args && PACK_EXPANSION_P (args))
return true;
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index bfeeebc2b38..cad5b217f3c 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -15044,6 +15044,94 @@ tsubst_exception_specification (tree fntype,
return new_specs;
}
+/* Substitute through a TREE_LIST of types or expressions, handling pack
+ expansions. */
+
+tree
+tsubst_tree_list (tree t, tree args, tsubst_flags_t complain, tree in_decl)
+{
+ if (t == void_list_node)
+ return t;
+
+ tree purpose = TREE_PURPOSE (t);
+ tree purposevec = NULL_TREE;
+ if (!purpose)
+ ;
+ else if (PACK_EXPANSION_P (purpose))
+ {
+ purpose = tsubst_pack_expansion (purpose, args, complain, in_decl);
+ if (TREE_CODE (purpose) == TREE_VEC)
+ purposevec = purpose;
+ }
+ else if (TYPE_P (purpose))
+ purpose = tsubst (purpose, args, complain, in_decl);
+ else
+ purpose = tsubst_copy_and_build (purpose, args, complain, in_decl);
+ if (purpose == error_mark_node || purposevec == error_mark_node)
+ return error_mark_node;
+
+ tree value = TREE_VALUE (t);
+ tree valuevec = NULL_TREE;
+ if (!value)
+ ;
+ else if (PACK_EXPANSION_P (value))
+ {
+ value = tsubst_pack_expansion (value, args, complain, in_decl);
+ if (TREE_CODE (value) == TREE_VEC)
+ valuevec = value;
+ }
+ else if (TYPE_P (value))
+ value = tsubst (value, args, complain, in_decl);
+ else
+ value = tsubst_copy_and_build (value, args, complain, in_decl);
+ if (value == error_mark_node || valuevec == error_mark_node)
+ return error_mark_node;
+
+ tree chain = TREE_CHAIN (t);
+ if (!chain)
+ ;
+ else if (TREE_CODE (chain) == TREE_LIST)
+ chain = tsubst_tree_list (chain, args, complain, in_decl);
+ else if (TYPE_P (chain))
+ chain = tsubst (chain, args, complain, in_decl);
+ else
+ chain = tsubst_copy_and_build (chain, args, complain, in_decl);
+ if (chain == error_mark_node)
+ return error_mark_node;
+
+ if (purpose == TREE_PURPOSE (t)
+ && value == TREE_VALUE (t)
+ && chain == TREE_CHAIN (t))
+ return t;
+
+ int len;
+ /* Determine the number of arguments. */
+ if (purposevec)
+ {
+ len = TREE_VEC_LENGTH (purposevec);
+ gcc_assert (!valuevec || len == TREE_VEC_LENGTH (valuevec));
+ }
+ else if (valuevec)
+ len = TREE_VEC_LENGTH (valuevec);
+ else
+ len = 1;
+
+ for (int i = len; i-- > 0; )
+ {
+ if (purposevec)
+ purpose = TREE_VEC_ELT (purposevec, i);
+ if (valuevec)
+ value = TREE_VEC_ELT (valuevec, i);
+
+ if (value && TYPE_P (value))
+ chain = hash_tree_cons (purpose, value, chain);
+ else
+ chain = tree_cons (purpose, value, chain);
+ }
+
+ return chain;
+}
+
/* Take the tree structure T and replace template parameters used
therein with the argument vector ARGS. IN_DECL is an associated
decl for diagnostics. If an error occurs, returns ERROR_MARK_NODE.
@@ -15463,104 +15551,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
}
case TREE_LIST:
- {
- tree purpose, value, chain;
-
- if (t == void_list_node)
- return t;
-
- if ((TREE_PURPOSE (t) && PACK_EXPANSION_P (TREE_PURPOSE (t)))
- || (TREE_VALUE (t) && PACK_EXPANSION_P (TREE_VALUE (t))))
- {
- /* We have pack expansions, so expand those and
- create a new list out of it. */
-
- /* Expand the argument expressions. */
- tree purposevec = NULL_TREE;
- if (TREE_PURPOSE (t))
- purposevec = tsubst_pack_expansion (TREE_PURPOSE (t), args,
- complain, in_decl);
- if (purposevec == error_mark_node)
- return error_mark_node;
-
- tree valuevec = NULL_TREE;
- if (TREE_VALUE (t))
- valuevec = tsubst_pack_expansion (TREE_VALUE (t), args,
- complain, in_decl);
- if (valuevec == error_mark_node)
- return error_mark_node;
-
- /* Build the rest of the list. */
- tree chain = TREE_CHAIN (t);
- if (chain && chain != void_type_node)
- chain = tsubst (chain, args, complain, in_decl);
- if (chain == error_mark_node)
- return error_mark_node;
-
- /* Determine the number of arguments. */
- int len = -1;
- if (purposevec && TREE_CODE (purposevec) == TREE_VEC)
- {
- len = TREE_VEC_LENGTH (purposevec);
- gcc_assert (!valuevec || len == TREE_VEC_LENGTH (valuevec));
- }
- else if (TREE_CODE (valuevec) == TREE_VEC)
- len = TREE_VEC_LENGTH (valuevec);
- else
- {
- /* Since we only performed a partial substitution into
- the argument pack, we only RETURN (a single list
- node. */
- if (purposevec == TREE_PURPOSE (t)
- && valuevec == TREE_VALUE (t)
- && chain == TREE_CHAIN (t))
- return t;
-
- return tree_cons (purposevec, valuevec, chain);
- }
-
- /* Convert the argument vectors into a TREE_LIST. */
- for (int i = len; i-- > 0; )
- {
- purpose = (purposevec ? TREE_VEC_ELT (purposevec, i)
- : NULL_TREE);
- value = (valuevec ? TREE_VEC_ELT (valuevec, i)
- : NULL_TREE);
-
- /* Build the list (backwards). */
- chain = hash_tree_cons (purpose, value, chain);
- }
-
- return chain;
- }
-
- purpose = TREE_PURPOSE (t);
- if (purpose)
- {
- purpose = tsubst (purpose, args, complain, in_decl);
- if (purpose == error_mark_node)
- return error_mark_node;
- }
- value = TREE_VALUE (t);
- if (value)
- {
- value = tsubst (value, args, complain, in_decl);
- if (value == error_mark_node)
- return error_mark_node;
- }
- chain = TREE_CHAIN (t);
- if (chain && chain != void_type_node)
- {
- chain = tsubst (chain, args, complain, in_decl);
- if (chain == error_mark_node)
- return error_mark_node;
- }
- if (purpose == TREE_PURPOSE (t)
- && value == TREE_VALUE (t)
- && chain == TREE_CHAIN (t))
- return t;
- return hash_tree_cons (purpose, value, chain);
- }
+ return tsubst_tree_list (t, args, complain, in_decl);
case TREE_BINFO:
/* We should never be tsubsting a binfo. */
@@ -20078,90 +20069,7 @@ tsubst_copy_and_build (tree t,
}
case TREE_LIST:
- {
- tree purpose, value, chain;
-
- if (t == void_list_node)
- RETURN (t);
-
- if ((TREE_PURPOSE (t) && PACK_EXPANSION_P (TREE_PURPOSE (t)))
- || (TREE_VALUE (t) && PACK_EXPANSION_P (TREE_VALUE (t))))
- {
- /* We have pack expansions, so expand those and
- create a new list out of it. */
- tree purposevec = NULL_TREE;
- tree valuevec = NULL_TREE;
- tree chain;
- int i, len = -1;
-
- /* Expand the argument expressions. */
- if (TREE_PURPOSE (t))
- purposevec = tsubst_pack_expansion (TREE_PURPOSE (t), args,
- complain, in_decl);
- if (TREE_VALUE (t))
- valuevec = tsubst_pack_expansion (TREE_VALUE (t), args,
- complain, in_decl);
-
- /* Build the rest of the list. */
- chain = TREE_CHAIN (t);
- if (chain && chain != void_type_node)
- chain = RECUR (chain);
-
- /* Determine the number of arguments. */
- if (purposevec && TREE_CODE (purposevec) == TREE_VEC)
- {
- len = TREE_VEC_LENGTH (purposevec);
- gcc_assert (!valuevec || len == TREE_VEC_LENGTH (valuevec));
- }
- else if (TREE_CODE (valuevec) == TREE_VEC)
- len = TREE_VEC_LENGTH (valuevec);
- else
- {
- /* Since we only performed a partial substitution into
- the argument pack, we only RETURN (a single list
- node. */
- if (purposevec == TREE_PURPOSE (t)
- && valuevec == TREE_VALUE (t)
- && chain == TREE_CHAIN (t))
- RETURN (t);
-
- RETURN (tree_cons (purposevec, valuevec, chain));
- }
-
- /* Convert the argument vectors into a TREE_LIST */
- i = len;
- while (i > 0)
- {
- /* Grab the Ith values. */
- i--;
- purpose = purposevec ? TREE_VEC_ELT (purposevec, i)
- : NULL_TREE;
- value
- = valuevec ? convert_from_reference (TREE_VEC_ELT (valuevec, i))
- : NULL_TREE;
-
- /* Build the list (backwards). */
- chain = tree_cons (purpose, value, chain);
- }
-
- RETURN (chain);
- }
-
- purpose = TREE_PURPOSE (t);
- if (purpose)
- purpose = RECUR (purpose);
- value = TREE_VALUE (t);
- if (value)
- value = RECUR (value);
- chain = TREE_CHAIN (t);
- if (chain && chain != void_type_node)
- chain = RECUR (chain);
- if (purpose == TREE_PURPOSE (t)
- && value == TREE_VALUE (t)
- && chain == TREE_CHAIN (t))
- RETURN (t);
- RETURN (tree_cons (purpose, value, chain));
- }
+ RETURN (tsubst_tree_list (t, args, complain, in_decl));
case COMPONENT_REF:
{
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2020-08-22 21:17 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-08-22 21:17 [gcc/devel/autopar_devel] PR c++/93286 - ICE with __is_constructible and variadic template Giuliano Belinassi
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).