File tree Expand file tree Collapse file tree 3 files changed +29
-1
lines changed Expand file tree Collapse file tree 3 files changed +29
-1
lines changed Original file line number Diff line number Diff line change @@ -51,6 +51,11 @@ class Scope final {
5151 return llvm::make_range (Descriptors.begin (), Descriptors.end ());
5252 }
5353
54+ llvm::iterator_range<LocalVectorTy::const_reverse_iterator>
55+ locals_reverse () const {
56+ return llvm::reverse (Descriptors);
57+ }
58+
5459private:
5560 // / Object descriptors in this block.
5661 LocalVectorTy Descriptors;
Original file line number Diff line number Diff line change @@ -99,7 +99,7 @@ void InterpFrame::initScope(unsigned Idx) {
9999}
100100
101101void InterpFrame::destroy (unsigned Idx) {
102- for (auto &Local : Func->getScope (Idx).locals ()) {
102+ for (auto &Local : Func->getScope (Idx).locals_reverse ()) {
103103 S.deallocate (localBlock (Local.Offset ));
104104 }
105105}
Original file line number Diff line number Diff line change @@ -908,3 +908,26 @@ namespace TemporaryInNTTP {
908908 // expected-note {{created here}}
909909 B<2 > j2; // / Ok.
910910}
911+
912+ namespace LocalDestroy {
913+ // / This is reduced from a libc++ test case.
914+ // / The local f.TI.copied points to the local variable Copied, and we used to
915+ // / destroy Copied before f, causing problems later on when a DeadBlock had a
916+ // / pointer pointing to it that was already destroyed.
917+ struct TrackInitialization {
918+ bool *copied_;
919+ };
920+ struct TrackingPred : TrackInitialization {
921+ constexpr TrackingPred (bool *copied) : TrackInitialization(copied) {}
922+ };
923+ struct F {
924+ const TrackingPred &TI;
925+ };
926+ constexpr int f () {
927+ bool Copied = false ;
928+ TrackingPred TI (&Copied);
929+ F f{TI};
930+ return 1 ;
931+ }
932+ static_assert (f() == 1 );
933+ }
You can’t perform that action at this time.
0 commit comments