Skip to content

Commit 69aed81

Browse files
committed
P2242R3 Non-literal variables (and labels and gotos) in constexpr functions
1 parent 2360a59 commit 69aed81

File tree

3 files changed

+25
-21
lines changed

3 files changed

+25
-21
lines changed

source/declarations.tex

Lines changed: 13 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -783,21 +783,7 @@
783783

784784
\item
785785
if the function is a constructor or destructor,
786-
its class shall not have any virtual base classes;
787-
788-
\item
789-
its \grammarterm{function-body} shall not enclose\iref{stmt.pre}
790-
\begin{itemize}
791-
\item a \tcode{goto} statement,
792-
\item a label with an \grammarterm{identifier}\iref{stmt.label},
793-
\item a definition of a variable
794-
of non-literal type or
795-
of static or thread storage duration.
796-
\end{itemize}
797-
\begin{note}
798-
A \grammarterm{function-body} that is \tcode{= delete} or \tcode{= default}
799-
encloses none of the above.
800-
\end{note}
786+
its class shall not have any virtual base classes.
801787
\end{itemize}
802788

803789
\begin{example}
@@ -811,9 +797,12 @@
811797
x = -x;
812798
return x; // OK
813799
}
814-
constexpr int first(int n) {
815-
static int value = n; // error: variable has static storage duration
816-
return value;
800+
constexpr int constant_non_42(int n) { // OK
801+
if (n == 42) {
802+
static int value = n;
803+
return value;
804+
}
805+
return n;
817806
}
818807
constexpr int uninit() {
819808
struct { int a; } s;
@@ -892,6 +881,12 @@
892881
constexpr D() : B(global) { } // ill-formed, no diagnostic required
893882
// lvalue-to-rvalue conversion on non-constant \tcode{global}
894883
};
884+
885+
constexpr int f(int x) {
886+
static int n = x;
887+
return n + x; // ill-formed, no diagnostic required
888+
// all calls reach the static variable declaration
889+
}
895890
\end{codeblock}
896891
\end{example}
897892

source/expressions.tex

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7080,6 +7080,12 @@
70807080
function\iref{dcl.constexpr} that is being evaluated as part
70817081
of $E$;
70827082

7083+
\item
7084+
a control flow that passes through
7085+
a declaration of a variable with
7086+
static\iref{basic.stc.static} or
7087+
thread\iref{basic.stc.thread} storage duration;
7088+
70837089
\item
70847090
an invocation of a non-constexpr function;
70857091
\begin{footnote}
@@ -7249,10 +7255,13 @@
72497255
that would throw an exception;
72507256

72517257
\item
7252-
an \grammarterm{asm-declaration}\iref{dcl.asm}; or
7258+
an \grammarterm{asm-declaration}\iref{dcl.asm};
7259+
7260+
\item
7261+
an invocation of the \tcode{va_arg} macro\iref{cstdarg.syn}; or
72537262

72547263
\item
7255-
an invocation of the \tcode{va_arg} macro\iref{cstdarg.syn}.
7264+
a \tcode{goto} statement\iref{stmt.goto}.
72567265
\end{itemize}
72577266

72587267
If $E$ satisfies the constraints of a core constant expression, but

source/preprocessor.tex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1765,7 +1765,7 @@
17651765
\defnxname{cpp_char8_t} & \tcode{201811L} \\ \rowsep
17661766
\defnxname{cpp_concepts} & \tcode{201907L} \\ \rowsep
17671767
\defnxname{cpp_conditional_explicit} & \tcode{201806L} \\ \rowsep
1768-
\defnxname{cpp_constexpr} & \tcode{201907L} \\ \rowsep
1768+
\defnxname{cpp_constexpr} & \tcode{202110L} \\ \rowsep
17691769
\defnxname{cpp_constexpr_dynamic_alloc} & \tcode{201907L} \\ \rowsep
17701770
\defnxname{cpp_constexpr_in_decltype} & \tcode{201711L} \\ \rowsep
17711771
\defnxname{cpp_consteval} & \tcode{201811L} \\ \rowsep

0 commit comments

Comments
 (0)