[PR c++/87814] undefer deferred noexcept on tsubst if request
authorAlexandre Oliva <aoliva@redhat.com>
Fri, 14 Dec 2018 21:57:07 +0000 (21:57 +0000)
committerAlexandre Oliva <aoliva@gcc.gnu.org>
Fri, 14 Dec 2018 21:57:07 +0000 (21:57 +0000)
tsubst_expr and tsubst_copy_and_build are not expected to handle
DEFERRED_NOEXCEPT exprs, but if tsubst_exception_specification takes a
DEFERRED_NOEXCEPT expr with !defer_ok, it just passes the expr on for
tsubst_copy_and_build to barf.

This patch arranges for tsubst_exception_specification to combine the
incoming args with those already stored in a DEFERRED_NOEXCEPT, and
then substitute them into the pattern, when retaining a deferred
noexcept is unacceptable.

for  gcc/cp/ChangeLog

PR c++/87814
* pt.c (tsubst_exception_specification): Handle
DEFERRED_NOEXCEPT with !defer_ok.

for  gcc/testsuite/ChangeLog

PR c++/87814
* g++.dg/cpp1z/pr87814.C: New.

From-SVN: r267155

gcc/cp/ChangeLog
gcc/cp/pt.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp1z/pr87814.C [new file with mode: 0644]

index 0467ca2..2dfb1fe 100644 (file)
@@ -1,3 +1,9 @@
+2018-12-14  Alexandre Oliva <aoliva@redhat.com>
+
+       PR c++/87814
+       * pt.c (tsubst_exception_specification): Handle
+       DEFERRED_NOEXCEPT with !defer_ok.
+
 2018-12-14  Jason Merrill <jason@redhat.com>
 
        PR c++/86823
index 3b378ee..20f0d16 100644 (file)
@@ -14151,9 +14151,17 @@ tsubst_exception_specification (tree fntype,
            }
        }
       else
-       new_specs = tsubst_copy_and_build
-         (expr, args, complain, in_decl, /*function_p=*/false,
-          /*integral_constant_expression_p=*/true);
+       {
+         if (DEFERRED_NOEXCEPT_SPEC_P (specs))
+           {
+             args = add_to_template_args (DEFERRED_NOEXCEPT_ARGS (expr),
+                                          args);
+             expr = DEFERRED_NOEXCEPT_PATTERN (expr);
+           }
+         new_specs = tsubst_copy_and_build
+           (expr, args, complain, in_decl, /*function_p=*/false,
+            /*integral_constant_expression_p=*/true);
+       }
       new_specs = build_noexcept_spec (new_specs, complain);
     }
   else if (specs)
index a087916..9c24e47 100644 (file)
@@ -1,3 +1,8 @@
+2018-12-14  Alexandre Oliva <aoliva@redhat.com>
+
+       PR c++/87814
+       * g++.dg/cpp1z/pr87814.C: New.
+
 2018-12-14  H.J. Lu  <hongjiu.lu@intel.com>
 
        * gcc.target/i386/cf_check-1.c: New test.
diff --git a/gcc/testsuite/g++.dg/cpp1z/pr87814.C b/gcc/testsuite/g++.dg/cpp1z/pr87814.C
new file mode 100644 (file)
index 0000000..37034bb
--- /dev/null
@@ -0,0 +1,26 @@
+// { dg-do compile { target c++17 } }
+
+template<class Element>
+struct box {
+    template<class E>
+    constexpr box(E && e)
+        noexcept(noexcept(Element(e)))
+    {}
+};
+
+template<class... Ts>
+struct compressed_tuple_ : box<Ts> ... {
+    template<typename... Args>
+    constexpr compressed_tuple_(Args &&... args)
+        noexcept((noexcept(box<Ts>(args)) && ...))
+      : box<Ts>(args)...
+    {}
+};
+
+struct adaptor_cursor : compressed_tuple_<int*> {
+    using compressed_tuple_::compressed_tuple_;
+};
+
+int main() {
+    (void)noexcept(adaptor_cursor{(int*)0});
+}