]> git.ipfire.org Git - thirdparty/gcc.git/commit
c++: consteval blocks master trunk
authorMarek Polacek <polacek@redhat.com>
Mon, 14 Jul 2025 21:24:18 +0000 (17:24 -0400)
committerMarek Polacek <polacek@redhat.com>
Thu, 31 Jul 2025 14:40:28 +0000 (10:40 -0400)
commitd46d8267b5a55e3194e879e691aeee1bc0648bed
treee17e93e0051128d9ded932020c9c095011d5faf9
parent9c63518f3a6a6b8c517e147db30fd47b3e371175
c++: consteval blocks

This patch implements consteval blocks, as specified by P2996.
They aren't very useful without define_aggregate, but having
a reviewed implementation on trunk would be great.

consteval {} can be anywhere where a member-declaration or
block-declaration can be.  The expression corresponding to it is:

  [] -> void static consteval compound-statement ()

and it must be a constant expression.

I've used cp_parser_lambda_expression to take care of most of the
parsing.  Since a consteval block can find itself in a template, we
need a vehicle to carry the block for instantiation.  Rather than
inventing a new tree, I'm using STATIC_ASSERT.

A consteval block can't return a value but that is checked by virtue
of the lambda having a void return type.

PR c++/120775

gcc/cp/ChangeLog:

* constexpr.cc (cxx_eval_outermost_constant_expr): Use
extract_call_expr.
* cp-tree.h (CONSTEVAL_BLOCK_P, LAMBDA_EXPR_CONSTEVAL_BLOCK_P): Define.
(finish_static_assert): Adjust declaration.
(current_nonlambda_function): Likewise.
* lambda.cc (current_nonlambda_function): New parameter.  Only keep
iterating if the function represents a consteval block.
* parser.cc (cp_parser_lambda_expression): New parameter for
consteval blocks.  Use it.  Set LAMBDA_EXPR_CONSTEVAL_BLOCK_P.
(cp_parser_lambda_declarator_opt): Likewise.
(build_empty_string): New.
(cp_parser_next_tokens_are_consteval_block_p): New.
(cp_parser_consteval_block): New.
(cp_parser_block_declaration): Handle consteval blocks.
(cp_parser_static_assert): Use build_empty_string.
(cp_parser_member_declaration): Handle consteval blocks.
* pt.cc (tsubst_stmt): Adjust a call to finish_static_assert.
* semantics.cc (finish_fname): Warn for consteval blocks.
(finish_static_assert): New parameter for consteval blocks.  Set
CONSTEVAL_BLOCK_P.  Evaluate consteval blocks specially.

gcc/testsuite/ChangeLog:

* g++.dg/cpp26/consteval-block1.C: New test.
* g++.dg/cpp26/consteval-block2.C: New test.
* g++.dg/cpp26/consteval-block3.C: New test.
* g++.dg/cpp26/consteval-block4.C: New test.
* g++.dg/cpp26/consteval-block5.C: New test.
* g++.dg/cpp26/consteval-block6.C: New test.
* g++.dg/cpp26/consteval-block7.C: New test.
* g++.dg/cpp26/consteval-block8.C: New test.

Reviewed-by: Jason Merrill <jason@redhat.com>
14 files changed:
gcc/cp/constexpr.cc
gcc/cp/cp-tree.h
gcc/cp/lambda.cc
gcc/cp/parser.cc
gcc/cp/pt.cc
gcc/cp/semantics.cc
gcc/testsuite/g++.dg/cpp26/consteval-block1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp26/consteval-block2.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp26/consteval-block3.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp26/consteval-block4.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp26/consteval-block5.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp26/consteval-block6.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp26/consteval-block7.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp26/consteval-block8.C [new file with mode: 0644]