Skip to content

Commit fa07eb4

Browse files
authored
Merge 2022-11 CWG Motion 9
P2564R3 consteval needs to propagate up
2 parents 06bd91b + 52e0381 commit fa07eb4

File tree

3 files changed

+114
-13
lines changed

3 files changed

+114
-13
lines changed

source/declarations.tex

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -767,8 +767,10 @@
767767
used in the declaration of a function
768768
declares that function to be
769769
a \defnx{constexpr function}{specifier!\idxcode{constexpr}!function}.
770+
\begin{note}
770771
A function or constructor declared with the \keyword{consteval} specifier
771-
is called an \defnadj{immediate}{function}.
772+
is an immediate function\iref{expr.const}.
773+
\end{note}
772774
A destructor, an allocation function, or a deallocation function
773775
shall not be declared with the \keyword{consteval} specifier.
774776

source/expressions.tex

Lines changed: 110 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1372,15 +1372,6 @@
13721372
\end{example}
13731373
\end{itemize}
13741374

1375-
\pnum
1376-
A potentially-evaluated \grammarterm{id-expression}
1377-
that denotes an immediate function\iref{dcl.constexpr}
1378-
shall appear only
1379-
\begin{itemize}
1380-
\item as a subexpression of an immediate invocation, or
1381-
\item in an immediate function context\iref{expr.const}.
1382-
\end{itemize}
1383-
13841375
\pnum
13851376
For an \grammarterm{id-expression} that denotes an overload set,
13861377
overload resolution is performed
@@ -7853,7 +7844,10 @@
78537844
\begin{itemize}
78547845
\item
78557846
its innermost enclosing non-block scope is
7856-
a function parameter scope of an immediate function, or
7847+
a function parameter scope of an immediate function,
7848+
\item
7849+
it is a subexpression of a manifestly constant-evaluated expression
7850+
or conversion, or
78577851
\item
78587852
its enclosing statement is enclosed\iref{stmt.pre} by
78597853
the \grammarterm{compound-statement} of a consteval if statement\iref{stmt.if}.
@@ -7862,7 +7856,112 @@
78627856
if it is a potentially-evaluated explicit or implicit invocation of
78637857
an immediate function and
78647858
is not in an immediate function context.
7865-
An immediate invocation shall be a constant expression.
7859+
An aggregate initialization is an immediate invocation
7860+
if it evaluates a default member initializer
7861+
that has a subexpression that is an immediate-escalating expression.
7862+
7863+
\pnum
7864+
\indexdefn{expression!immediate-escalating}%
7865+
\indexdefn{conversion!immediate-escalating}%
7866+
\indexdefn{immediate-escalating!expression|see{expression, immediate-escalating}}%
7867+
\indexdefn{immediate-escalating!conversion|see{conversion, immediate-escalating}}%
7868+
An expression or conversion is \defn{immediate-escalating}
7869+
if it is not initially in an immediate function context
7870+
and it is either
7871+
\begin{itemize}
7872+
\item
7873+
a potentially-evaluated \grammarterm{id-expression}
7874+
that denotes an immediate function
7875+
that is not a subexpression of an immediate invocation, or
7876+
\item
7877+
an immediate invocation that is not a constant expression
7878+
and is not a subexpression of an immediate invocation.
7879+
\end{itemize}
7880+
7881+
\pnum
7882+
\indexdefn{immediate-escalating!function|see{function, immediate-escalating}}%
7883+
An \defnx{immediate-escalating}{function!immediate-escalating} function is
7884+
\begin{itemize}
7885+
\item
7886+
the call operator of a lambda that is not declared
7887+
with the \keyword{consteval} specifier,
7888+
\item
7889+
a defaulted special member function
7890+
that is not declared with the \keyword{consteval} specifier, or
7891+
\item
7892+
a function that results from the instantiation
7893+
of a templated entity defined with the \keyword{constexpr} specifier.
7894+
\end{itemize}
7895+
An immediate-escalating expression shall appear only
7896+
in an immediate-escalating function.
7897+
7898+
\pnum
7899+
An \defnadj{immediate}{function} is a function or constructor that is
7900+
\begin{itemize}
7901+
\item
7902+
declared with the \keyword{consteval} specifier, or
7903+
\item
7904+
an immediate-escalating function \tcode{\placeholder{F}}
7905+
whose function body contains an immediate-escalating expression \tcode{\placeholder{E}}
7906+
such that \tcode{\placeholder{E}}'s innermost enclosing non-block scope
7907+
is \tcode{\placeholder{F}}'s function parameter scope.
7908+
\end{itemize}
7909+
\begin{example}
7910+
\begin{codeblock}
7911+
consteval int id(int i) { return i; }
7912+
constexpr char id(char c) { return c; }
7913+
7914+
template<class T>
7915+
constexpr int f(T t) {
7916+
return t + id(t);
7917+
}
7918+
7919+
auto a = &f<char>; // OK, \tcode{f<char>} is not an immediate function
7920+
auto b = &f<int>; // error: \tcode{f<int>} is an immediate function
7921+
7922+
static_assert(f(3) == 6); // OK
7923+
7924+
template<class T>
7925+
constexpr int g(T t) { // \tcode{g<int>} is not an immediate function
7926+
return t + id(42); // because \tcode{id(42)} is already a constant
7927+
}
7928+
7929+
template<class T, class F>
7930+
constexpr bool is_not(T t, F f) {
7931+
return not f(t);
7932+
}
7933+
7934+
consteval bool is_even(int i) { return i % 2 == 0; }
7935+
7936+
static_assert(is_not(5, is_even)); // OK
7937+
7938+
int x = 0;
7939+
7940+
template<class T>
7941+
constexpr T h(T t = id(x)) { // \tcode{h<int>} is not an immediate function
7942+
return t;
7943+
}
7944+
7945+
template<class T>
7946+
constexpr T hh() { // \tcode{hh<int>} is an immediate function
7947+
return h<T>();
7948+
}
7949+
7950+
int i = hh<int>(); // error: ill-formed, \tcode{hh<int>()} is an immediate-escalating expression
7951+
// outside of an immediate-escalating function
7952+
7953+
struct A {
7954+
int x;
7955+
int y = id(x);
7956+
};
7957+
7958+
template<class T>
7959+
constexpr int k(int) { // \tcode{k<int>} is not an immediate function because \tcode{A(42)} is a
7960+
return A(42).y; // constant expression and thus not immediate-escalating
7961+
}
7962+
\end{codeblock}
7963+
\end{example}
7964+
78667965

78677966
\pnum
78687967
An expression or conversion is \defn{manifestly constant-evaluated}

source/preprocessor.tex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1804,7 +1804,7 @@
18041804
\defnxname{cpp_constexpr} & \tcode{202211L} \\ \rowsep
18051805
\defnxname{cpp_constexpr_dynamic_alloc} & \tcode{201907L} \\ \rowsep
18061806
\defnxname{cpp_constexpr_in_decltype} & \tcode{201711L} \\ \rowsep
1807-
\defnxname{cpp_consteval} & \tcode{201811L} \\ \rowsep
1807+
\defnxname{cpp_consteval} & \tcode{202211L} \\ \rowsep
18081808
\defnxname{cpp_constinit} & \tcode{201907L} \\ \rowsep
18091809
\defnxname{cpp_decltype} & \tcode{200707L} \\ \rowsep
18101810
\defnxname{cpp_decltype_auto} & \tcode{201304L} \\ \rowsep

0 commit comments

Comments
 (0)