From 47722e915d2f6d0fbebc84b82d502faa53bdc0c8 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Mon, 7 Jun 2021 22:43:33 +0200 Subject: [PATCH] P1938R3 if consteval --- source/expressions.tex | 10 ++++++-- source/preprocessor.tex | 1 + source/statements.tex | 53 +++++++++++++++++++++++++++++++++++++++++ source/utilities.tex | 13 ++++++---- 4 files changed, 71 insertions(+), 6 deletions(-) diff --git a/source/expressions.tex b/source/expressions.tex index 0383ec9d7e..15c009135e 100644 --- a/source/expressions.tex +++ b/source/expressions.tex @@ -7465,9 +7465,15 @@ \pnum An expression or conversion is in an \defn{immediate function context} -if it is potentially evaluated and +if it is potentially evaluated and either: +\begin{itemize} +\item its innermost enclosing non-block scope is -a function parameter scope of an immediate function. +a function parameter scope of an immediate function, or +\item +its enclosing statement is enclosed\iref{stmt.pre} by +the \grammarterm{compound-statement} of a consteval if statement\iref{stmt.if}. +\end{itemize} An expression or conversion is an \defn{immediate invocation} if it is a potentially-evaluated explicit or implicit invocation of an immediate function and diff --git a/source/preprocessor.tex b/source/preprocessor.tex index 436aa27844..37715aa88f 100644 --- a/source/preprocessor.tex +++ b/source/preprocessor.tex @@ -1780,6 +1780,7 @@ \defnxname{cpp_generic_lambdas} & \tcode{201707L} \\ \rowsep \defnxname{cpp_guaranteed_copy_elision} & \tcode{201606L} \\ \rowsep \defnxname{cpp_hex_float} & \tcode{201603L} \\ \rowsep +\defnxname{cpp_if_consteval} & \tcode{202106L} \\ \rowsep \defnxname{cpp_if_constexpr} & \tcode{201606L} \\ \rowsep \defnxname{cpp_impl_coroutine} & \tcode{201902L} \\ \rowsep \defnxname{cpp_impl_destroying_delete} & \tcode{201806L} \\ \rowsep diff --git a/source/statements.tex b/source/statements.tex index 95d406a899..cf608ae87c 100644 --- a/source/statements.tex +++ b/source/statements.tex @@ -212,6 +212,8 @@ \nontermdef{selection-statement}\br \keyword{if} \opt{\keyword{constexpr}} \terminal{(} \opt{init-statement} condition \terminal{)} statement\br \keyword{if} \opt{\keyword{constexpr}} \terminal{(} \opt{init-statement} condition \terminal{)} statement \keyword{else} statement\br + \keyword{if} \opt{\terminal{!}} \keyword{consteval} compound-statement\br + \keyword{if} \opt{\terminal{!}} \keyword{consteval} compound-statement \keyword{else} statement\br \keyword{switch} \terminal{(} \opt{init-statement} condition \terminal{)} statement \end{bnf} @@ -315,6 +317,57 @@ except that the \grammarterm{init-statement} is in the same scope as the \grammarterm{condition}. +\pnum +An \keyword{if} statement of the form \tcode{\keyword{if} \keyword{consteval}} +is called a \defnadj{consteval if}{statement}. +The \grammarterm{statement}, if any, in a consteval if statement +shall be a \grammarterm{compound-statement}. +\begin{example} +\begin{codeblock} +constexpr void f(bool b) { + if (true) + if consteval { } + else ; // error: not a \grammarterm{compound-statement}; \keyword{else} not associated with outer \keyword{if} +} +\end{codeblock} +\end{example} + +\pnum +If a consteval if statement is evaluated in a context +that is manifestly constant-evaluated\iref{expr.const}, +the first substatement is executed. +\begin{note} +The first substatement is an immediate function context. +\end{note} +Otherwise, if the \keyword{else} part of the selection statement is present, +then the second substatement is executed. +A \keyword{case} or \keyword{default} label +appearing within such an \keyword{if} statement +shall be associated with a \keyword{switch} statement +within the same \keyword{if} statement. +A label declared in a substatement of a consteval if statement +shall only be referred to by a statement in the same substatement. + +\pnum +An \keyword{if} statement of the form +\begin{ncsimplebnf} +\keyword{if} \terminal{!} \keyword{consteval} compound-statement +\end{ncsimplebnf} +is not itself a consteval if statement, +but is equivalent to the consteval if statement +\begin{ncsimplebnf} +\keyword{if} \keyword{consteval} \terminal{\{} \terminal{\}} \keyword{else} compound-statement +\end{ncsimplebnf} +An \keyword{if} statement of the form +\begin{ncsimplebnf} +\keyword{if} \terminal{!} \keyword{consteval} compound-statement$_1$ \keyword{else} statement$_2$ +\end{ncsimplebnf} +is not itself a consteval if statement, +but is equivalent to the consteval if statement +\begin{ncsimplebnf} +\keyword{if} \keyword{consteval} statement$_2$ \keyword{else} compound-statement$_1$ +\end{ncsimplebnf} + \rSec2[stmt.switch]{The \tcode{switch} statement}% \indextext{statement!\idxcode{switch}} diff --git a/source/utilities.tex b/source/utilities.tex index 9f206dc7f9..4d404bedec 100644 --- a/source/utilities.tex +++ b/source/utilities.tex @@ -18143,10 +18143,15 @@ \begin{itemdescr} \pnum -\returns -\tcode{true} if and only if evaluation of the call occurs -within the evaluation of an expression or conversion -that is manifestly constant-evaluated\iref{expr.const}. +\effects +Equivalent to: +\begin{codeblock} +if consteval { + return true; +} else { + return false; +} +\end{codeblock} \pnum \begin{example}