Message ID | ora7likx2f.fsf@lxoliva.fsfla.org |
---|---|
State | New |
Headers | show |
Series | [C++,PR,c++/87814] undefer deferred noexcept on tsubst if request | expand |
On Dec 6, 2018, Alexandre Oliva <aoliva@redhat.com> wrote: > Regstrapped on x86_64- and i686-linux-gnu, mistakenly along with a patch > with a known regression, and got only that known regression. Retesting > without it. Ok to install? Ping? That retesting confirmed no regressions. https://gcc.gnu.org/ml/gcc-patches/2018-12/msg00423.html > 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.
On 12/6/18 7:19 PM, Alexandre Oliva wrote: > 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. > > Regstrapped on x86_64- and i686-linux-gnu, mistakenly along with a patch > with a known regression, and got only that known regression. Retesting > without it. Ok to install? OK. Jason
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 8560e5885933..72ae7173d92c 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -14150,9 +14150,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) diff --git a/gcc/testsuite/g++.dg/cpp1z/pr87814.C b/gcc/testsuite/g++.dg/cpp1z/pr87814.C new file mode 100644 index 000000000000..37034bb58cd6 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1z/pr87814.C @@ -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}); +}