On Thu, Sep 5, 2019 at 2:14 PM Marek Polacek <pola...@redhat.com> wrote: > > This patch implements C++20 P1286R2, Contra CWG DR1778 as described here > <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1286r2.html>. > Essentially, it removes the restriction that the exception specification of > a defaulted special member matches the implicit exception specification. > "Implementing" it means just removing some code (woo!) that was marking > a function DECL_DELETED_FN if the exception-specifications didn't match... > > ...except there's a snag. We no longer reject > > struct A { > A() noexcept(false) = default; > }; > > because A::A() is no longer deleted. But this assert fails: > > static_assert(!noexcept(A()), ""); > > and it doesn't seem to me it should, but it's sort of Catch 22. The default > constructor *is* trivial as per [class.default.ctor]/3, so trivial_fn_p is > true. When build_over_call sees a default_ctor_p that is trivial_fn_p, it > elides the call and creates a TARGET_EXPR <D, void_cst>. When evaluating > noexcept(A()) expr_noexcept_p gets TARGET_EXPR <D, {}> and since there is > no CALL_EXPR/AGGR_INIT_EXPR that throws, it says "ok, this can't throw". > > [except.spec]/6: An expression e is potentially-throwing if > (6.1) e is a function call [...] with a potentially-throwing exception > specification, or > (6.2) e implicitly invokes a function [...] that is potentially-throwing, or > ... > (6.6) any of the immediate subexpressions of e is potentially-throwing.
> which of these apply here, 6.1? But such a TARGET_EXPR can't throw, can it? Ah, interesting. It seems to me that a trivial function should not be considered potentially-throwing. I'm not sure whether it's best to address this by making it non-trivial or overriding the exception specification. I think the definition of potentially-throwing is not the right place to fix it. Do you want to email CWG or shall I? Jason