The first test is rejected because build_noexcept_spec first converts a TARGET_EXPR using a user-defined conversion, creating
R::operator bool (&TARGET_EXPR <D.2323, {}>) which then fails when instantiating ("taking address of rvalue"). The second test ICEs in verify_ctor_sanity because there was no ctx.ctor when evaluating the TARGET_EXPR. That is expected, because we create constructors for class and vector types (and PMFs I guess) only, not for scalars. We need finish_compound_literal to turn TARGET_EXPR <D.2306, {}> into TARGET_EXPR <D.2307, 0> Fixed both by handling the noexcept expr like we handle the explicit expr in build_explicit_specifier. Bootstrapped/regtested on x86_64-linux, ok for trunk and 9? 2019-06-20 Marek Polacek <pola...@redhat.com> PR c++/90490 - fix decltype issues in noexcept-specifier. * except.c (build_noexcept_spec): Call instantiate_non_dependent_expr_sfinae before build_converted_constant_expr instead of calling instantiate_non_dependent_expr after it. Add processing_template_decl_sentinel. * g++.dg/cpp0x/noexcept43.C: New test. * g++.dg/cpp0x/noexcept44.C: New test. diff --git gcc/cp/except.c gcc/cp/except.c index 892d5201da9..71f5d609f10 100644 --- gcc/cp/except.c +++ gcc/cp/except.c @@ -1285,8 +1285,10 @@ build_noexcept_spec (tree expr, tsubst_flags_t complain) if (TREE_CODE (expr) != DEFERRED_NOEXCEPT && !value_dependent_expression_p (expr)) { + expr = instantiate_non_dependent_expr_sfinae (expr, complain); + /* Don't let convert_like_real create more template codes. */ + processing_template_decl_sentinel s; expr = build_converted_constant_bool_expr (expr, complain); - expr = instantiate_non_dependent_expr (expr); expr = cxx_constant_value (expr); } if (TREE_CODE (expr) == INTEGER_CST) diff --git gcc/testsuite/g++.dg/cpp0x/noexcept43.C gcc/testsuite/g++.dg/cpp0x/noexcept43.C new file mode 100644 index 00000000000..faa7d146029 --- /dev/null +++ gcc/testsuite/g++.dg/cpp0x/noexcept43.C @@ -0,0 +1,10 @@ +// PR c++/90490 +// { dg-do compile { target c++11 } } + +struct R { constexpr operator bool() { return false;} }; + +template <typename> +struct S { + void g() noexcept(decltype(R{ }) { }) { + } +}; diff --git gcc/testsuite/g++.dg/cpp0x/noexcept44.C gcc/testsuite/g++.dg/cpp0x/noexcept44.C new file mode 100644 index 00000000000..78c9d12f2b7 --- /dev/null +++ gcc/testsuite/g++.dg/cpp0x/noexcept44.C @@ -0,0 +1,8 @@ +// PR c++/90490 +// { dg-do compile { target c++11 } } + +template <typename> +struct S { + void g() noexcept(decltype(int{ }) { }) { + } +};