On 9/10/24 8:35 PM, Patrick Palka wrote:
Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for
trunk/backports?

OK, though you might combine the new STMT_EXPR case with the existing LAMBDA_EXPR case; the principle is the same for both.

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

Reply via email to