@@ -83,6 +83,17 @@ static void diagnoseMissingInitializer(InterpState &S, CodePtr OpPC,
8383 S.Note (VD->getLocation (), diag::note_declared_at) << VD->getSourceRange ();
8484}
8585
86+ static void noteValueLocation (InterpState &S, const Block *B) {
87+ const Descriptor *Desc = B->getDescriptor ();
88+
89+ if (B->isDynamic ())
90+ S.Note (Desc->getLocation (), diag::note_constexpr_dynamic_alloc_here);
91+ else if (B->isTemporary ())
92+ S.Note (Desc->getLocation (), diag::note_constexpr_temporary_here);
93+ else
94+ S.Note (Desc->getLocation (), diag::note_declared_at);
95+ }
96+
8697static void diagnoseNonConstVariable (InterpState &S, CodePtr OpPC,
8798 const ValueDecl *VD);
8899static bool diagnoseUnknownDecl (InterpState &S, CodePtr OpPC,
@@ -185,8 +196,7 @@ static bool CheckTemporary(InterpState &S, CodePtr OpPC, const Block *B,
185196 !MTE->isUsableInConstantExpressions (S.getASTContext ())) {
186197 const SourceInfo &E = S.Current ->getSource (OpPC);
187198 S.FFDiag (E, diag::note_constexpr_access_static_temporary, 1 ) << AK;
188- S.Note (B->getDescriptor ()->getLocation (),
189- diag::note_constexpr_temporary_here);
199+ noteValueLocation (S, B);
190200 return false ;
191201 }
192202 }
@@ -418,14 +428,9 @@ bool CheckLive(InterpState &S, CodePtr OpPC, const Pointer &Ptr,
418428 if (Ptr.isDynamic ()) {
419429 S.FFDiag (Src, diag::note_constexpr_access_deleted_object) << AK;
420430 } else if (!S.checkingPotentialConstantExpression ()) {
421- bool IsTemp = Ptr.isTemporary ();
422431 S.FFDiag (Src, diag::note_constexpr_access_uninit)
423432 << AK << /* uninitialized=*/ false << S.Current ->getRange (OpPC);
424-
425- if (IsTemp)
426- S.Note (Ptr.getDeclLoc (), diag::note_constexpr_temporary_here);
427- else
428- S.Note (Ptr.getDeclLoc (), diag::note_declared_at);
433+ noteValueLocation (S, Ptr.block ());
429434 }
430435
431436 return false ;
@@ -648,14 +653,16 @@ bool DiagnoseUninitialized(InterpState &S, CodePtr OpPC, const Pointer &Ptr,
648653 AccessKinds AK) {
649654 assert (Ptr.isLive ());
650655 assert (!Ptr.isInitialized ());
651- return DiagnoseUninitialized (S, OpPC, Ptr.isExtern (), Ptr.getDeclDesc (), AK);
656+ return DiagnoseUninitialized (S, OpPC, Ptr.isExtern (), Ptr.block (), AK);
652657}
653658
654659bool DiagnoseUninitialized (InterpState &S, CodePtr OpPC, bool Extern,
655- const Descriptor *Desc , AccessKinds AK) {
660+ const Block *B , AccessKinds AK) {
656661 if (Extern && S.checkingPotentialConstantExpression ())
657662 return false ;
658663
664+ const Descriptor *Desc = B->getDescriptor ();
665+
659666 if (const auto *VD = Desc->asVarDecl ();
660667 VD && (VD->isConstexpr () || VD->hasGlobalStorage ())) {
661668
@@ -670,6 +677,7 @@ bool DiagnoseUninitialized(InterpState &S, CodePtr OpPC, bool Extern,
670677 // Diagnose as "read of object outside its lifetime".
671678 S.FFDiag (Loc, diag::note_constexpr_access_uninit)
672679 << AK << /* IsIndeterminate=*/ false ;
680+ S.Note (VD->getLocation (), diag::note_declared_at);
673681 }
674682 return false ;
675683 }
@@ -687,21 +695,27 @@ bool DiagnoseUninitialized(InterpState &S, CodePtr OpPC, bool Extern,
687695 if (!S.checkingPotentialConstantExpression ()) {
688696 S.FFDiag (S.Current ->getSource (OpPC), diag::note_constexpr_access_uninit)
689697 << AK << /* uninitialized=*/ true << S.Current ->getRange (OpPC);
698+ noteValueLocation (S, B);
690699 }
691700 return false ;
692701}
693702
694703static bool CheckLifetime (InterpState &S, CodePtr OpPC, Lifetime LT,
695- AccessKinds AK) {
704+ const Block *B, AccessKinds AK) {
696705 if (LT == Lifetime::Started)
697706 return true ;
698707
699708 if (!S.checkingPotentialConstantExpression ()) {
700709 S.FFDiag (S.Current ->getSource (OpPC), diag::note_constexpr_access_uninit)
701710 << AK << /* uninitialized=*/ false << S.Current ->getRange (OpPC);
711+ noteValueLocation (S, B);
702712 }
703713 return false ;
704714}
715+ static bool CheckLifetime (InterpState &S, CodePtr OpPC, const Pointer &Ptr,
716+ AccessKinds AK) {
717+ return CheckLifetime (S, OpPC, Ptr.getLifetime (), Ptr.block (), AK);
718+ }
705719
706720static bool CheckWeak (InterpState &S, CodePtr OpPC, const Block *B) {
707721 if (!B->isWeak ())
@@ -733,8 +747,7 @@ bool CheckGlobalLoad(InterpState &S, CodePtr OpPC, const Block *B) {
733747 if (!CheckConstant (S, OpPC, B->getDescriptor ()))
734748 return false ;
735749 if (Desc.InitState != GlobalInitState::Initialized)
736- return DiagnoseUninitialized (S, OpPC, B->isExtern (), B->getDescriptor (),
737- AK_Read);
750+ return DiagnoseUninitialized (S, OpPC, B->isExtern (), B, AK_Read);
738751 if (!CheckTemporary (S, OpPC, B, AK_Read))
739752 return false ;
740753 if (B->getDescriptor ()->IsVolatile ) {
@@ -755,11 +768,10 @@ bool CheckGlobalLoad(InterpState &S, CodePtr OpPC, const Block *B) {
755768bool CheckLocalLoad (InterpState &S, CodePtr OpPC, const Block *B) {
756769 assert (!B->isExtern ());
757770 const auto &Desc = *reinterpret_cast <const InlineDescriptor *>(B->rawData ());
758- if (!CheckLifetime (S, OpPC, Desc.LifeState , AK_Read))
771+ if (!CheckLifetime (S, OpPC, Desc.LifeState , B, AK_Read))
759772 return false ;
760773 if (!Desc.IsInitialized )
761- return DiagnoseUninitialized (S, OpPC, /* Extern=*/ false , B->getDescriptor (),
762- AK_Read);
774+ return DiagnoseUninitialized (S, OpPC, /* Extern=*/ false , B, AK_Read);
763775 if (B->getDescriptor ()->IsVolatile ) {
764776 if (!S.getLangOpts ().CPlusPlus )
765777 return Invalid (S, OpPC);
@@ -805,7 +817,7 @@ bool CheckLoad(InterpState &S, CodePtr OpPC, const Pointer &Ptr,
805817 return false ;
806818 if (!CheckActive (S, OpPC, Ptr, AK))
807819 return false ;
808- if (!CheckLifetime (S, OpPC, Ptr. getLifetime () , AK))
820+ if (!CheckLifetime (S, OpPC, Ptr, AK))
809821 return false ;
810822 if (!Ptr.isInitialized ())
811823 return DiagnoseUninitialized (S, OpPC, Ptr, AK);
@@ -843,7 +855,7 @@ bool CheckFinalLoad(InterpState &S, CodePtr OpPC, const Pointer &Ptr) {
843855
844856 if (!CheckActive (S, OpPC, Ptr, AK_Read))
845857 return false ;
846- if (!CheckLifetime (S, OpPC, Ptr. getLifetime () , AK_Read))
858+ if (!CheckLifetime (S, OpPC, Ptr, AK_Read))
847859 return false ;
848860 if (!Ptr.isInitialized ())
849861 return DiagnoseUninitialized (S, OpPC, Ptr, AK_Read);
@@ -868,7 +880,7 @@ bool CheckStore(InterpState &S, CodePtr OpPC, const Pointer &Ptr,
868880 return false ;
869881 return CheckDummy (S, OpPC, Ptr.block (), AK_Assign);
870882 }
871- if (!CheckLifetime (S, OpPC, Ptr. getLifetime () , AK_Assign))
883+ if (!CheckLifetime (S, OpPC, Ptr, AK_Assign))
872884 return false ;
873885 if (!CheckRange (S, OpPC, Ptr, AK_Assign))
874886 return false ;
@@ -1138,11 +1150,7 @@ bool CheckDeleteSource(InterpState &S, CodePtr OpPC, const Expr *Source,
11381150 const SourceInfo &Loc = S.Current ->getSource (OpPC);
11391151 S.FFDiag (Loc, diag::note_constexpr_delete_not_heap_alloc)
11401152 << Ptr.toDiagnosticString (S.getASTContext ());
1141-
1142- if (Ptr.isTemporary ())
1143- S.Note (Ptr.getDeclLoc (), diag::note_constexpr_temporary_here);
1144- else
1145- S.Note (Ptr.getDeclLoc (), diag::note_declared_at);
1153+ noteValueLocation (S, Ptr.block ());
11461154 return false ;
11471155}
11481156
@@ -1505,7 +1513,7 @@ bool CheckDestructor(InterpState &S, CodePtr OpPC, const Pointer &Ptr) {
15051513 return false ;
15061514 if (!CheckRange (S, OpPC, Ptr, AK_Destroy))
15071515 return false ;
1508- if (!CheckLifetime (S, OpPC, Ptr. getLifetime () , AK_Destroy))
1516+ if (!CheckLifetime (S, OpPC, Ptr, AK_Destroy))
15091517 return false ;
15101518
15111519 // Can't call a dtor on a global variable.
@@ -2028,7 +2036,7 @@ bool CheckNewTypeMismatch(InterpState &S, CodePtr OpPC, const Expr *E,
20282036
20292037 // CheckLifetime for this and all base pointers.
20302038 for (Pointer P = Ptr;;) {
2031- if (!CheckLifetime (S, OpPC, P. getLifetime () , AK_Construct))
2039+ if (!CheckLifetime (S, OpPC, P, AK_Construct))
20322040 return false ;
20332041
20342042 if (P.isRoot ())
0 commit comments