Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for
trunk/backports?

-- >8 --

r8-7538 for PR84968 made strip_typedefs_expr diagnose seeing
STATEMENT_LIST, which effectively makes us reject statement-expressions
noexcept-specifiers (we already diagnose them in template arguments
at parse time).

Later r11-7452 made decltype(auto) deduction do strip_typedefs_expr on
the expression before deducing (as an implementation detail) and so ever
since we inadvertently reject decltype(auto) deduction of a
statement-expression.

This patch just removes the diagnostic in strip_typedefs_expr; it doesn't
seem like the right place for it.  And it lets us accept more code using
statement-expressions in various contexts.

        PR c++/116418
        PR c++/84968

gcc/cp/ChangeLog:

        * tree.cc (strip_typedefs_expr) <case STATEMENT_LIST>: Replace
        with ...
        <case STMT_EXPR>: ... this non-diagnosing early exit.

gcc/testsuite/ChangeLog:

        * g++.dg/eh/pr84968.C: No longer expect ah ahead of time diagnostic
        for the statement-expresssion.  Instantiate the template and expect
        an incomplete type error instead.
        * g++.dg/ext/stmtexpr26.C: New test.
---
 gcc/cp/tree.cc                        |  5 ++---
 gcc/testsuite/g++.dg/eh/pr84968.C     |  4 +++-
 gcc/testsuite/g++.dg/ext/stmtexpr26.C | 10 ++++++++++
 3 files changed, 15 insertions(+), 4 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/ext/stmtexpr26.C

diff --git a/gcc/cp/tree.cc b/gcc/cp/tree.cc
index 31ecbb1ac79..a150a91f2fa 100644
--- a/gcc/cp/tree.cc
+++ b/gcc/cp/tree.cc
@@ -2011,9 +2011,8 @@ strip_typedefs_expr (tree t, bool *remove_attributes, 
unsigned int flags)
     case LAMBDA_EXPR:
       return t;
 
-    case STATEMENT_LIST:
-      error ("statement-expression in a constant expression");
-      return error_mark_node;
+    case STMT_EXPR:
+      return t;
 
     default:
       break;
diff --git a/gcc/testsuite/g++.dg/eh/pr84968.C 
b/gcc/testsuite/g++.dg/eh/pr84968.C
index 23c49f477a8..a6e21914eed 100644
--- a/gcc/testsuite/g++.dg/eh/pr84968.C
+++ b/gcc/testsuite/g++.dg/eh/pr84968.C
@@ -9,7 +9,9 @@ struct S {
   void a()
     try {
     } catch (int ()
-            noexcept (({ union b a; true; }))) // { dg-error "constant" }
+            noexcept (({ union b a; true; }))) // { dg-error "'b a' has 
incomplete type" }
   {
   }
 };
+
+template void S::a<int>(); // { dg-message "required from here" }
diff --git a/gcc/testsuite/g++.dg/ext/stmtexpr26.C 
b/gcc/testsuite/g++.dg/ext/stmtexpr26.C
new file mode 100644
index 00000000000..498dd12ef10
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/stmtexpr26.C
@@ -0,0 +1,10 @@
+// PR c++/116418
+// { dg-do compile { target c++14 } }
+
+void foo ();
+template <typename>
+void bar ()
+{
+  decltype(auto) v = ({ foo (); 3; });
+}
+
-- 
2.46.0.540.g4c42d5ff28

Reply via email to