@@ -3510,6 +3510,7 @@ static bool evaluateVarDeclInit(EvalInfo &Info, const Expr *E,
35103510 // P2280R4 struck the restriction that variable of reference type lifetime
35113511 // should begin within the evaluation of E
35123512 // Used to be C++20 [expr.const]p5.12.2:
3513+ // ... its lifetime began within the evaluation of E;
35133514 if (isa<ParmVarDecl>(VD) && !AllowConstexprUnknown) {
35143515 // Assume parameters of a potential constant expression are usable in
35153516 // constant expressions.
@@ -3537,6 +3538,7 @@ static bool evaluateVarDeclInit(EvalInfo &Info, const Expr *E,
35373538 // P2280R4 struck the restriction that variable of reference type should have
35383539 // a preceding initialization.
35393540 // Used to be C++20 [expr.const]p5.12:
3541+ // ... reference has a preceding initialization and either ...
35403542 if (!Init && !AllowConstexprUnknown) {
35413543 // Don't diagnose during potential constant expression checking; an
35423544 // initializer might be added later.
@@ -3550,6 +3552,8 @@ static bool evaluateVarDeclInit(EvalInfo &Info, const Expr *E,
35503552
35513553 // P2280R4 struck the initialization requirement for variables of reference
35523554 // type so we can no longer assume we have an Init.
3555+ // Used to be C++20 [expr.const]p5.12:
3556+ // ... reference has a preceding initialization and either ...
35533557 if (Init && Init->isValueDependent()) {
35543558 // The DeclRefExpr is not value-dependent, but the variable it refers to
35553559 // has a value-dependent initializer. This should only happen in
@@ -3571,6 +3575,8 @@ static bool evaluateVarDeclInit(EvalInfo &Info, const Expr *E,
35713575 // this in the cases where it matters for conformance.
35723576 // P2280R4 struck the initialization requirement for variables of reference
35733577 // type so we can no longer assume we have an Init.
3578+ // Used to be C++20 [expr.const]p5.12:
3579+ // ... reference has a preceding initialization and either ...
35743580 if (Init && !VD->evaluateValue()) {
35753581 if (AllowConstexprUnknown) {
35763582 Result = &Info.CurrentCall->createConstexprUnknownAPValues(VD, Base);
@@ -3608,9 +3614,13 @@ static bool evaluateVarDeclInit(EvalInfo &Info, const Expr *E,
36083614
36093615 Result = VD->getEvaluatedValue();
36103616
3611- // P2280R4 If we don't have a value because this is a reference that was not
3612- // initialized or whose lifetime began within E then create a value with as
3613- // a ConstexprUnknown status.
3617+ // C++23 [expr.const]p8
3618+ // ... For such an object that is not usable in constant expressions, the
3619+ // dynamic type of the object is constexpr-unknown. For such a reference that
3620+ // is not usable in constant expressions, the reference is treated as binding
3621+ // to an unspecified object of the referenced type whose lifetime and that of
3622+ // all subobjects includes the entire constant evaluation and whose dynamic
3623+ // type is constexpr-unknown.
36143624 if (AllowConstexprUnknown) {
36153625 if (!Result) {
36163626 Result = &Info.CurrentCall->createConstexprUnknownAPValues(VD, Base);
@@ -5966,9 +5976,12 @@ struct CheckDynamicTypeHandler {
59665976/// dynamic type.
59675977static bool checkDynamicType(EvalInfo &Info, const Expr *E, const LValue &This,
59685978 AccessKinds AK, bool Polymorphic) {
5969- // P2280R4 We are not allowed to invoke a virtual function whose dynamic type
5979+ // We are not allowed to invoke a virtual function whose dynamic type
59705980 // is constexpr-unknown, so stop early and let this fail later on if we
59715981 // attempt to do so.
5982+ // C++23 [expr.const]p5.6
5983+ // an invocation of a virtual function ([class.virtual]) for an object whose
5984+ // dynamic type is constexpr-unknown;
59725985 if (This.allowConstexprUnknown())
59735986 return true;
59745987
0 commit comments