Skip to content

Commit 1c0063b

Browse files
committed
[clang][Interp] Remove StoragKind limitation in Pointer assign operators
It's not strictly needed and did cause some test failures.
1 parent 36bc741 commit 1c0063b

File tree

2 files changed

+37
-22
lines changed

2 files changed

+37
-22
lines changed

clang/lib/AST/Interp/Pointer.cpp

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -64,53 +64,53 @@ Pointer::~Pointer() {
6464
}
6565

6666
void Pointer::operator=(const Pointer &P) {
67-
if (!this->isIntegralPointer() || !P.isBlockPointer())
68-
assert(P.StorageKind == StorageKind || (this->isZero() && P.isZero()));
69-
67+
// If the current storage type is Block, we need to remove
68+
// this pointer from the block.
7069
bool WasBlockPointer = isBlockPointer();
71-
StorageKind = P.StorageKind;
7270
if (StorageKind == Storage::Block) {
7371
Block *Old = PointeeStorage.BS.Pointee;
74-
if (WasBlockPointer && PointeeStorage.BS.Pointee)
72+
if (WasBlockPointer && Old) {
7573
PointeeStorage.BS.Pointee->removePointer(this);
74+
Old->cleanup();
75+
}
76+
}
7677

77-
Offset = P.Offset;
78+
StorageKind = P.StorageKind;
79+
Offset = P.Offset;
80+
81+
if (P.isBlockPointer()) {
7882
PointeeStorage.BS = P.PointeeStorage.BS;
7983

8084
if (PointeeStorage.BS.Pointee)
8185
PointeeStorage.BS.Pointee->addPointer(this);
82-
83-
if (WasBlockPointer && Old)
84-
Old->cleanup();
85-
86-
} else if (StorageKind == Storage::Int) {
86+
} else if (P.isIntegralPointer()) {
8787
PointeeStorage.Int = P.PointeeStorage.Int;
8888
} else {
8989
assert(false && "Unhandled storage kind");
9090
}
9191
}
9292

9393
void Pointer::operator=(Pointer &&P) {
94-
if (!this->isIntegralPointer() || !P.isBlockPointer())
95-
assert(P.StorageKind == StorageKind || (this->isZero() && P.isZero()));
96-
94+
// If the current storage type is Block, we need to remove
95+
// this pointer from the block.
9796
bool WasBlockPointer = isBlockPointer();
98-
StorageKind = P.StorageKind;
9997
if (StorageKind == Storage::Block) {
10098
Block *Old = PointeeStorage.BS.Pointee;
101-
if (WasBlockPointer && PointeeStorage.BS.Pointee)
99+
if (WasBlockPointer && Old) {
102100
PointeeStorage.BS.Pointee->removePointer(this);
101+
Old->cleanup();
102+
}
103+
}
103104

104-
Offset = P.Offset;
105+
StorageKind = P.StorageKind;
106+
Offset = P.Offset;
107+
108+
if (P.isBlockPointer()) {
105109
PointeeStorage.BS = P.PointeeStorage.BS;
106110

107111
if (PointeeStorage.BS.Pointee)
108112
PointeeStorage.BS.Pointee->addPointer(this);
109-
110-
if (WasBlockPointer && Old)
111-
Old->cleanup();
112-
113-
} else if (StorageKind == Storage::Int) {
113+
} else if (P.isIntegralPointer()) {
114114
PointeeStorage.Int = P.PointeeStorage.Int;
115115
} else {
116116
assert(false && "Unhandled storage kind");

clang/test/AST/Interp/cxx20.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -782,3 +782,18 @@ namespace APValues {
782782
constexpr const A &v = get<A{}>;
783783
constexpr const A &w = get<A{1, &g, &A::n, "hello"}>;
784784
}
785+
786+
namespace self_referencing {
787+
struct S {
788+
S* ptr = nullptr;
789+
constexpr S(int i) : ptr(this) {
790+
if (this == ptr && i)
791+
ptr = nullptr;
792+
}
793+
constexpr ~S() {}
794+
};
795+
796+
void test() {
797+
S s(1);
798+
}
799+
}

0 commit comments

Comments
 (0)