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); + } +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits