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{ }) { }) {
+  }
+};

Reply via email to