Skip to content

Commit 63a1dd7

Browse files
authored
Merge 2022-07 CWG Motion 13
P2280R4 Using unknown pointers and references in constant expressions
2 parents b1ccaad + 32d8f9c commit 63a1dd7

File tree

1 file changed

+84
-21
lines changed

1 file changed

+84
-21
lines changed

source/expressions.tex

Lines changed: 84 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -7289,9 +7289,15 @@
72897289
machine\iref{intro.execution}, would evaluate one of the following:
72907290
\begin{itemize}
72917291
\item
7292-
\keyword{this}\iref{expr.prim.this}, except in a constexpr
7293-
function\iref{dcl.constexpr} that is being evaluated as part
7294-
of $E$;
7292+
\keyword{this}\iref{expr.prim.this}, except
7293+
\begin{itemize}
7294+
\item
7295+
in a constexpr function\iref{dcl.constexpr}
7296+
that is being evaluated as part of $E$ or
7297+
\item
7298+
when appearing as the \grammarterm{postfix-expression} of
7299+
an implicit or explicit class member access expression\iref{expr.ref};
7300+
\end{itemize}
72957301

72967302
\item
72977303
a control flow that passes through
@@ -7316,11 +7322,7 @@
73167322

73177323
\item
73187324
an invocation of a virtual function\iref{class.virtual}
7319-
for an object unless
7320-
\begin{itemize}
7321-
\item the object is usable in constant expressions or
7322-
\item its lifetime began within the evaluation of $E$;
7323-
\end{itemize}
7325+
for an object whose dynamic type is constexpr-unknown;
73247326

73257327
\item
73267328
an expression that would exceed the implementation-defined
@@ -7364,18 +7366,6 @@
73647366
for a union whose active member (if any) is mutable,
73657367
unless the lifetime of the union object began within the evaluation of $E$;
73667368

7367-
\item
7368-
an \grammarterm{id-expression} that refers to a variable or
7369-
data member of reference type
7370-
unless the reference has a preceding initialization and either
7371-
\begin{itemize}
7372-
\item
7373-
it is usable in constant expressions or
7374-
7375-
\item
7376-
its lifetime began within the evaluation of $E$;
7377-
\end{itemize}
7378-
73797369
\item
73807370
in a \grammarterm{lambda-expression},
73817371
a reference to \keyword{this} or to a variable with
@@ -7467,7 +7457,10 @@
74677457
a \grammarterm{throw-expression}\iref{expr.throw};
74687458

74697459
\item
7470-
a \keyword{dynamic_cast}\iref{expr.dynamic.cast} or \keyword{typeid}\iref{expr.typeid} expression
7460+
a \keyword{dynamic_cast}\iref{expr.dynamic.cast} or
7461+
\keyword{typeid}\iref{expr.typeid} expression
7462+
on a glvalue that refers to an object
7463+
whose dynamic type is constexpr-unknown or
74717464
that would throw an exception;
74727465

74737466
\item
@@ -7549,6 +7542,71 @@
75497542
the evaluation of the underlying constructor call
75507543
disqualifies $E$ from being a core constant expression.
75517544

7545+
\pnum
7546+
During the evaluation of an expression $E$ as a core constant expression,
7547+
all \grammarterm{id-expression}s and uses of \tcode{*\keyword{this}}
7548+
that refer to an object or reference
7549+
whose lifetime did not begin with the evaluation of $E$
7550+
are treated as referring to a specific instance of that object or reference
7551+
whose lifetime and that of all subobjects (including all union members)
7552+
includes the entire constant evaluation.
7553+
For such an object that is not usable in constant expressions,
7554+
the dynamic type of the object is \defn{constexpr-unknown}.
7555+
For such a reference that is not usable in constant expressions,
7556+
the reference is treated as binding to
7557+
an unspecified object of the referenced type
7558+
whose lifetime and that of all subobjects includes
7559+
the entire constant evaluation and whose dynamic type is constexpr-unknown.
7560+
\begin{example}
7561+
\begin{codeblock}
7562+
template <typename T, size_t N>
7563+
constexpr size_t array_size(T (&)[N]) {
7564+
return N;
7565+
}
7566+
7567+
void use_array(int const (&gold_medal_mel)[2]) {
7568+
constexpr auto gold = array_size(gold_medal_mel); // OK
7569+
}
7570+
7571+
constexpr auto olympic_mile() {
7572+
const int ledecky = 1500;
7573+
return []{ return ledecky; };
7574+
}
7575+
static_assert(olympic_mile()() == 1500); // OK
7576+
7577+
struct Swim {
7578+
constexpr int phelps() { return 28; }
7579+
virtual constexpr int lochte() { return 12; }
7580+
int coughlin = 12;
7581+
};
7582+
7583+
constexpr int how_many(Swim& swam) {
7584+
Swim* p = &swam;
7585+
return (p + 1 - 1)->phelps();
7586+
}
7587+
7588+
void splash(Swim& swam) {
7589+
static_assert(swam.phelps() == 28); // OK
7590+
static_assert((&swam)->phelps() == 28); // OK
7591+
Swim* pswam = &swam;
7592+
static_assert(pswam->phelps() == 28); // error: lvalue-to-rvalue conversion on a pointer
7593+
// not usable in constant expressions
7594+
static_assert(how_many(swam) == 28); // OK
7595+
static_assert(Swim().lochte() == 12); // OK
7596+
static_assert(swam.lochte() == 12); // error: invoking virtual function on reference
7597+
// with constexpr-unknown dynamic type
7598+
static_assert(swam.coughlin == 12); // error: lvalue-to-rvalue conversion on an object
7599+
// not usable in constant expressions
7600+
}
7601+
7602+
extern Swim dc;
7603+
extern Swim& trident;
7604+
7605+
constexpr auto& sandeno = typeid(dc); // OK, can only be \tcode{typeid(Swim)}
7606+
constexpr auto& gallagher = typeid(trident); // error: constexpr-unknown dynamic type
7607+
\end{codeblock}
7608+
\end{example}
7609+
75527610
\pnum
75537611
An object \tcode{a} is said to have \defnadj{constant}{destruction} if:
75547612
\begin{itemize}
@@ -7662,6 +7720,11 @@
76627720
object with static storage duration that either is not a temporary object or is
76637721
a temporary object whose value satisfies the above constraints, or if
76647722
it is a non-immediate function.
7723+
\begin{note}
7724+
A glvalue core constant expression
7725+
that either refers to or points to an unspecified object
7726+
is not a constant expression.
7727+
\end{note}
76657728
\begin{example}
76667729
\begin{codeblock}
76677730
consteval int f() { return 42; }

0 commit comments

Comments
 (0)