diff mbox series

c++: decltype(auto) deduction of statement-expression [PR116418]

Message ID 20240911003521.2691563-1-ppalka@redhat.com
State New
Headers show
Series c++: decltype(auto) deduction of statement-expression [PR116418] | expand

Commit Message

Patrick Palka Sept. 11, 2024, 12:35 a.m. UTC
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

Comments

Jason Merrill Sept. 11, 2024, 3:30 p.m. UTC | #1
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; });
> +}
> +
diff mbox series

Patch

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