[clang] 1c0063b - [clang][Interp] Remove StoragKind limitation in Pointer assign operators
Timm Bäder via cfe-commits
cfe-commits at lists.llvm.org
Fri Jun 7 01:32:46 PDT 2024
Author: Timm Bäder
Date: 2024-06-07T10:32:16+02:00
New Revision: 1c0063b58a4fc23c94c7f5bf5a937bbdf9703cc0
URL: https://github.com/llvm/llvm-project/commit/1c0063b58a4fc23c94c7f5bf5a937bbdf9703cc0
DIFF: https://github.com/llvm/llvm-project/commit/1c0063b58a4fc23c94c7f5bf5a937bbdf9703cc0.diff
LOG: [clang][Interp] Remove StoragKind limitation in Pointer assign operators
It's not strictly needed and did cause some test failures.
Added:
Modified:
clang/lib/AST/Interp/Pointer.cpp
clang/test/AST/Interp/cxx20.cpp
Removed:
################################################################################
diff --git a/clang/lib/AST/Interp/Pointer.cpp b/clang/lib/AST/Interp/Pointer.cpp
index a60b4d28b4387..e3d21f93f114e 100644
--- a/clang/lib/AST/Interp/Pointer.cpp
+++ b/clang/lib/AST/Interp/Pointer.cpp
@@ -64,26 +64,26 @@ Pointer::~Pointer() {
}
void Pointer::operator=(const Pointer &P) {
- if (!this->isIntegralPointer() || !P.isBlockPointer())
- assert(P.StorageKind == StorageKind || (this->isZero() && P.isZero()));
-
+ // If the current storage type is Block, we need to remove
+ // this pointer from the block.
bool WasBlockPointer = isBlockPointer();
- StorageKind = P.StorageKind;
if (StorageKind == Storage::Block) {
Block *Old = PointeeStorage.BS.Pointee;
- if (WasBlockPointer && PointeeStorage.BS.Pointee)
+ if (WasBlockPointer && Old) {
PointeeStorage.BS.Pointee->removePointer(this);
+ Old->cleanup();
+ }
+ }
- Offset = P.Offset;
+ StorageKind = P.StorageKind;
+ Offset = P.Offset;
+
+ if (P.isBlockPointer()) {
PointeeStorage.BS = P.PointeeStorage.BS;
if (PointeeStorage.BS.Pointee)
PointeeStorage.BS.Pointee->addPointer(this);
-
- if (WasBlockPointer && Old)
- Old->cleanup();
-
- } else if (StorageKind == Storage::Int) {
+ } else if (P.isIntegralPointer()) {
PointeeStorage.Int = P.PointeeStorage.Int;
} else {
assert(false && "Unhandled storage kind");
@@ -91,26 +91,26 @@ void Pointer::operator=(const Pointer &P) {
}
void Pointer::operator=(Pointer &&P) {
- if (!this->isIntegralPointer() || !P.isBlockPointer())
- assert(P.StorageKind == StorageKind || (this->isZero() && P.isZero()));
-
+ // If the current storage type is Block, we need to remove
+ // this pointer from the block.
bool WasBlockPointer = isBlockPointer();
- StorageKind = P.StorageKind;
if (StorageKind == Storage::Block) {
Block *Old = PointeeStorage.BS.Pointee;
- if (WasBlockPointer && PointeeStorage.BS.Pointee)
+ if (WasBlockPointer && Old) {
PointeeStorage.BS.Pointee->removePointer(this);
+ Old->cleanup();
+ }
+ }
- Offset = P.Offset;
+ StorageKind = P.StorageKind;
+ Offset = P.Offset;
+
+ if (P.isBlockPointer()) {
PointeeStorage.BS = P.PointeeStorage.BS;
if (PointeeStorage.BS.Pointee)
PointeeStorage.BS.Pointee->addPointer(this);
-
- if (WasBlockPointer && Old)
- Old->cleanup();
-
- } else if (StorageKind == Storage::Int) {
+ } else if (P.isIntegralPointer()) {
PointeeStorage.Int = P.PointeeStorage.Int;
} else {
assert(false && "Unhandled storage kind");
diff --git a/clang/test/AST/Interp/cxx20.cpp b/clang/test/AST/Interp/cxx20.cpp
index 49ee040be392e..c750be866ca7c 100644
--- a/clang/test/AST/Interp/cxx20.cpp
+++ b/clang/test/AST/Interp/cxx20.cpp
@@ -782,3 +782,18 @@ namespace APValues {
constexpr const A &v = get<A{}>;
constexpr const A &w = get<A{1, &g, &A::n, "hello"}>;
}
+
+namespace self_referencing {
+ struct S {
+ S* ptr = nullptr;
+ constexpr S(int i) : ptr(this) {
+ if (this == ptr && i)
+ ptr = nullptr;
+ }
+ constexpr ~S() {}
+ };
+
+ void test() {
+ S s(1);
+ }
+}
More information about the cfe-commits
mailing list