PR c++/91378 - ICE with noexcept and auto return type.
authorJason Merrill <jason@redhat.com>
Tue, 6 Aug 2019 14:07:59 +0000 (10:07 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Tue, 6 Aug 2019 14:07:59 +0000 (10:07 -0400)
Here, since the call to g is not type-dependent, we call mark_used on it to
determine its return type.  This also wants to instantiate the
noexcept-expression.  But since nothing in maybe_instantiate_noexcept was
calling push_to_top_level, we substituted b.i with processing_template_decl
set, so we left it unresolved for later access checking.  As a result, the
type of C::g<int> remained instantiation-dependent, leading to an ICE in
type_dependent_expression_p on the assert that the type of a function
template with no dependent template arguments must be non-dependent.

* pt.c (maybe_instantiate_noexcept): push_to_top_level.

From-SVN: r274143

gcc/cp/ChangeLog
gcc/cp/pt.c
gcc/testsuite/g++.dg/cpp1y/auto-fn56.C [new file with mode: 0644]

index e541932..9b0a34c 100644 (file)
@@ -1,3 +1,8 @@
+2019-08-06  Jason Merrill  <jason@redhat.com>
+
+       PR c++/91378 - ICE with noexcept and auto return type.
+       * pt.c (maybe_instantiate_noexcept): push_to_top_level.
+
 2019-08-06  Paolo Carlini  <paolo.carlini@oracle.com>
 
        * decl.c (check_array_designated_initializer): Use
index 903e589..b71fbaa 100644 (file)
@@ -24315,12 +24315,11 @@ maybe_instantiate_noexcept (tree fn, tsubst_flags_t complain)
        }
       else if (push_tinst_level (fn))
        {
+         push_to_top_level ();
          push_access_scope (fn);
          push_deferring_access_checks (dk_no_deferred);
          input_location = DECL_SOURCE_LOCATION (fn);
 
-         tree save_ccp = current_class_ptr;
-         tree save_ccr = current_class_ref;
          /* If needed, set current_class_ptr for the benefit of
             tsubst_copy/PARM_DECL.  */
          tree tdecl = DECL_TEMPLATE_RESULT (DECL_TI_TEMPLATE (fn));
@@ -24346,9 +24345,6 @@ maybe_instantiate_noexcept (tree fn, tsubst_flags_t complain)
                                        /*function_p=*/false,
                                        /*i_c_e_p=*/true);
 
-         current_class_ptr = save_ccp;
-         current_class_ref = save_ccr;
-
          /* Build up the noexcept-specification.  */
          spec = build_noexcept_spec (noex, tf_warning_or_error);
 
@@ -24358,6 +24354,7 @@ maybe_instantiate_noexcept (tree fn, tsubst_flags_t complain)
          pop_deferring_access_checks ();
          pop_access_scope (fn);
          pop_tinst_level ();
+         pop_from_top_level ();
        }
       else
        spec = noexcept_false_spec;
diff --git a/gcc/testsuite/g++.dg/cpp1y/auto-fn56.C b/gcc/testsuite/g++.dg/cpp1y/auto-fn56.C
new file mode 100644 (file)
index 0000000..69bdd95
--- /dev/null
@@ -0,0 +1,19 @@
+// PR c++/91378
+// { dg-do compile { target c++14 } }
+
+struct B
+{
+  int i;
+};
+
+struct C
+{
+  template <class T> static auto
+  g(B b) noexcept(noexcept(b.i)) { }
+};
+
+template <class T>
+void h(T t)
+{
+  C::g<int>({});
+}