aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Malcolm <dmalcolm@redhat.com>2019-01-15 23:29:15 +0000
committerDavid Malcolm <dmalcolm@gcc.gnu.org>2019-01-15 23:29:15 +0000
commit1abb44f863d32ef738d28144d2c984603e27721a (patch)
tree763017fbe03c5c3da080d2a793ac9c587929f4f1
parentb7ec44e82bb50bd3adc294aa7e87252c79ea7294 (diff)
downloadgcc-1abb44f863d32ef738d28144d2c984603e27721a.zip
gcc-1abb44f863d32ef738d28144d2c984603e27721a.tar.gz
gcc-1abb44f863d32ef738d28144d2c984603e27721a.tar.bz2
Fix ICE on class-template argument deduction (PR c++/88795)
PR c++/88795 reports an ICE building a function_type for a deduction guide when the substitution into the function signature fails, due to an error_mark_node being returned from tsubst_arg_types but not being checked for. This error_mark_node gets used as the TYPE_ARG_TYPES, leading to ICEs in various places that assume this is a TREE_LIST. This patch checks the result of tsubst_arg_types and propagates the failure if it returns error_mark_node. It also adds an assertion to build_function_type, to fail faster if passed in error_mark_node. gcc/cp/ChangeLog: PR c++/88795 * pt.c (build_deduction_guide): Bail out if tsubst_arg_types fails. gcc/testsuite/ChangeLog: PR c++/88795 * g++.dg/template/pr88795.C: New test. gcc/ChangeLog: PR c++/88795 * tree.c (build_function_type): Assert that arg_types is not error_mark_node. From-SVN: r267957
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/pt.c2
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/template/pr88795.C23
-rw-r--r--gcc/tree.c2
6 files changed, 44 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 83d4fa4..e1ae217 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2019-01-15 David Malcolm <dmalcolm@redhat.com>
+
+ PR c++/88795
+ * tree.c (build_function_type): Assert that arg_types is not
+ error_mark_node.
+
2019-01-15 Richard Sandiford <richard.sandiford@arm.com>
PR inline-asm/52813
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 35eec34..7cf0ffb 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,9 @@
+2019-01-15 David Malcolm <dmalcolm@redhat.com>
+
+ PR c++/88795
+ * pt.c (build_deduction_guide): Bail out if tsubst_arg_types
+ fails.
+
2019-01-15 Paolo Carlini <paolo.carlini@oracle.com>
* decl.c (start_decl): Improve error location.
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index f062a2b..c6fc1cf 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -26932,6 +26932,8 @@ build_deduction_guide (tree ctor, tree outer_args, tsubst_flags_t complain)
targs = template_parms_to_args (tparms);
fparms = tsubst_arg_types (fparms, tsubst_args, NULL_TREE,
complain, ctor);
+ if (fparms == error_mark_node)
+ ok = false;
fargs = tsubst (fargs, tsubst_args, complain, ctor);
if (ci)
ci = tsubst_constraint_info (ci, tsubst_args, complain, ctor);
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index ec8a0c1..d226aa5 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2019-01-15 David Malcolm <dmalcolm@redhat.com>
+
+ PR c++/88795
+ * g++.dg/template/pr88795.C: New test.
+
2019-01-15 Thomas Koenig <tkoenig@gcc.gnu.org>
PR fortran/43136
diff --git a/gcc/testsuite/g++.dg/template/pr88795.C b/gcc/testsuite/g++.dg/template/pr88795.C
new file mode 100644
index 0000000..918aa6d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/pr88795.C
@@ -0,0 +1,23 @@
+// { dg-do compile { target c++17 } }
+
+template<class, int>
+struct Array {};
+
+template<class T, int size_>
+struct Foo {
+ static constexpr int size() {
+ return size_;
+ }
+
+ template<class U>
+ Foo(U, Array<T, size()>) {}
+};
+
+template<class T, int size, class U>
+Foo(U, Array<T, size>) -> Foo<T, size>;
+
+int main() {
+ Array<int, 2> arr{};
+
+ Foo foo{2.0, arr};
+}
diff --git a/gcc/tree.c b/gcc/tree.c
index 2e112ee..9e55499 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -8455,6 +8455,8 @@ build_function_type (tree value_type, tree arg_types)
bool any_structural_p, any_noncanonical_p;
tree canon_argtypes;
+ gcc_assert (arg_types != error_mark_node);
+
if (TREE_CODE (value_type) == FUNCTION_TYPE)
{
error ("function return type cannot be function");