[PATCH] Fix ICE on class-template argument deduction (PR c++/88795)

David Malcolm dmalcolm@redhat.com
Tue Jan 15 18:42:00 GMT 2019


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.

Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu.

OK for trunk?

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.
---
 gcc/cp/pt.c                             |  2 ++
 gcc/testsuite/g++.dg/template/pr88795.C | 23 +++++++++++++++++++++++
 gcc/tree.c                              |  2 ++
 3 files changed, 27 insertions(+)
 create mode 100644 gcc/testsuite/g++.dg/template/pr88795.C

diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 9473241..ba3b112 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -26909,6 +26909,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/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 2c0a09d..850fc61 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");
-- 
1.8.5.3



More information about the Gcc-patches mailing list