File tree 3 files changed +29
-1
lines changed 3 files changed +29
-1
lines changed Original file line number Diff line number Diff line change @@ -51,6 +51,11 @@ class Scope final {
51
51
return llvm::make_range (Descriptors.begin (), Descriptors.end ());
52
52
}
53
53
54
+ llvm::iterator_range<LocalVectorTy::const_reverse_iterator>
55
+ locals_reverse () const {
56
+ return llvm::reverse (Descriptors);
57
+ }
58
+
54
59
private:
55
60
// / Object descriptors in this block.
56
61
LocalVectorTy Descriptors;
Original file line number Diff line number Diff line change @@ -99,7 +99,7 @@ void InterpFrame::initScope(unsigned Idx) {
99
99
}
100
100
101
101
void InterpFrame::destroy (unsigned Idx) {
102
- for (auto &Local : Func->getScope (Idx).locals ()) {
102
+ for (auto &Local : Func->getScope (Idx).locals_reverse ()) {
103
103
S.deallocate (localBlock (Local.Offset ));
104
104
}
105
105
}
Original file line number Diff line number Diff line change @@ -908,3 +908,26 @@ namespace TemporaryInNTTP {
908
908
// expected-note {{created here}}
909
909
B<2 > j2; // / Ok.
910
910
}
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