https://github.com/ojhunt updated 
https://github.com/llvm/llvm-project/pull/137102

>From dec6509a54940fdda77577c9d07e1c061701ab75 Mon Sep 17 00:00:00 2001
From: Oliver Hunt <oli...@apple.com>
Date: Wed, 23 Apr 2025 18:09:22 -0700
Subject: [PATCH] [clang][p2719] Module deserialization does not restore
 allocator flags

When serializing and deserializing a FunctionDecl we don't recover
whether or not the decl was a type aware allocator or destroying
delete, because in the final PR that information was placed in a
side table in ASTContext.

In principle it should be possible to re-do the semantic checks to
determine what these flags should be when deserializing, but it
seems like the most robust path is simply recording the flags
directly in the serialized AST.
---
 clang/lib/Serialization/ASTReaderDecl.cpp     |  2 +
 clang/lib/Serialization/ASTWriterDecl.cpp     |  2 +
 .../Modules/Inputs/PR137102/module.modulemap  |  1 +
 .../type_aware_destroying_new_delete.h        | 52 +++++++++++++++++++
 ...ware-destroying-new-and-delete-modules.cpp | 23 ++++++++
 .../Inputs/type_aware_destroying_new_delete.h | 52 +++++++++++++++++++
 ...pe-aware-destroying-new-and-delete-pch.cpp | 27 ++++++++++
 7 files changed, 159 insertions(+)
 create mode 100644 clang/test/Modules/Inputs/PR137102/module.modulemap
 create mode 100644 
clang/test/Modules/Inputs/PR137102/type_aware_destroying_new_delete.h
 create mode 100644 
clang/test/Modules/type-aware-destroying-new-and-delete-modules.cpp
 create mode 100644 clang/test/PCH/Inputs/type_aware_destroying_new_delete.h
 create mode 100644 clang/test/PCH/type-aware-destroying-new-and-delete-pch.cpp

diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp 
b/clang/lib/Serialization/ASTReaderDecl.cpp
index 5545cbc8d608c..0f54aa5c5e062 100644
--- a/clang/lib/Serialization/ASTReaderDecl.cpp
+++ b/clang/lib/Serialization/ASTReaderDecl.cpp
@@ -1076,6 +1076,8 @@ void ASTDeclReader::VisitFunctionDecl(FunctionDecl *FD) {
   FD->setFriendConstraintRefersToEnclosingTemplate(
       FunctionDeclBits.getNextBit());
   FD->setUsesSEHTry(FunctionDeclBits.getNextBit());
+  FD->setIsDestroyingOperatorDelete(FunctionDeclBits.getNextBit());
+  FD->setIsTypeAwareOperatorNewOrDelete(FunctionDeclBits.getNextBit());
 
   FD->EndRangeLoc = readSourceLocation();
   if (FD->isExplicitlyDefaulted())
diff --git a/clang/lib/Serialization/ASTWriterDecl.cpp 
b/clang/lib/Serialization/ASTWriterDecl.cpp
index 3a7a23481ea98..d1f92cea4dfea 100644
--- a/clang/lib/Serialization/ASTWriterDecl.cpp
+++ b/clang/lib/Serialization/ASTWriterDecl.cpp
@@ -847,6 +847,8 @@ void ASTDeclWriter::VisitFunctionDecl(FunctionDecl *D) {
   FunctionDeclBits.addBit(D->isInstantiatedFromMemberTemplate());
   FunctionDeclBits.addBit(D->FriendConstraintRefersToEnclosingTemplate());
   FunctionDeclBits.addBit(D->usesSEHTry());
+  FunctionDeclBits.addBit(D->isDestroyingOperatorDelete());
+  FunctionDeclBits.addBit(D->isTypeAwareOperatorNewOrDelete());
   Record.push_back(FunctionDeclBits);
 
   Record.AddSourceLocation(D->getEndLoc());
diff --git a/clang/test/Modules/Inputs/PR137102/module.modulemap 
b/clang/test/Modules/Inputs/PR137102/module.modulemap
new file mode 100644
index 0000000000000..337aff5821e7f
--- /dev/null
+++ b/clang/test/Modules/Inputs/PR137102/module.modulemap
@@ -0,0 +1 @@
+module type_aware_destroying_new_delete { header 
"type_aware_destroying_new_delete.h" export * }
diff --git 
a/clang/test/Modules/Inputs/PR137102/type_aware_destroying_new_delete.h 
b/clang/test/Modules/Inputs/PR137102/type_aware_destroying_new_delete.h
new file mode 100644
index 0000000000000..f96a9ea0c8a41
--- /dev/null
+++ b/clang/test/Modules/Inputs/PR137102/type_aware_destroying_new_delete.h
@@ -0,0 +1,52 @@
+
+namespace std {
+    struct destroying_delete_t { };
+    template <class T> struct type_identity {
+        using type = T;
+    };
+    typedef __SIZE_TYPE__ size_t;
+    enum class align_val_t : size_t;
+};
+
+struct A {
+    A();
+   void *operator new(std::size_t);
+   void operator delete(A*, std::destroying_delete_t);
+};
+
+struct B {
+    B();
+    void *operator new(std::type_identity<B>, std::size_t, std::align_val_t);
+    void operator delete(std::type_identity<B>, void*, std::size_t, 
std::align_val_t);
+};
+
+struct C {
+    C();
+    template <class T> void *operator new(std::type_identity<T>, std::size_t, 
std::align_val_t);
+    template <class T> void operator delete(std::type_identity<T>, void*, 
std::size_t, std::align_val_t);
+};
+
+struct D {
+    D();
+};
+void *operator new(std::type_identity<D>, std::size_t, std::align_val_t);
+void operator delete(std::type_identity<D>, void*, std::size_t, 
std::align_val_t);
+
+struct E {
+    E();
+};
+template <class T> void *operator new(std::type_identity<T>, std::size_t, 
std::align_val_t);
+template <class T> void operator delete(std::type_identity<T>, void*, 
std::size_t, std::align_val_t);
+
+void in_module_tests() {
+  A* a = new A;
+  delete a;
+  B *b = new B;
+  delete b;
+  C *c = new C;
+  delete c;
+  D *d = new D;
+  delete d;
+  E *e = new E;
+  delete e;
+}
diff --git 
a/clang/test/Modules/type-aware-destroying-new-and-delete-modules.cpp 
b/clang/test/Modules/type-aware-destroying-new-and-delete-modules.cpp
new file mode 100644
index 0000000000000..e88f8a8791147
--- /dev/null
+++ b/clang/test/Modules/type-aware-destroying-new-and-delete-modules.cpp
@@ -0,0 +1,23 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -x c++ -std=c++26 
-fmodules-cache-path=%t -I %S/Inputs/PR137102 -emit-llvm-only %s
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -x c++ -std=c++26 
-fmodules-cache-path=%t -I %S/Inputs/PR137102 -emit-llvm-only %s -triple 
i686-windows
+
+#include "type_aware_destroying_new_delete.h"
+
+
+static void call_in_module_function(void) {
+    in_module_tests();
+}
+
+void out_of_module_tests() {
+    A* a = new A;
+    delete a;
+    B *b = new B;
+    delete b;
+    C *c = new C;
+    delete c;
+    D *d = new D;
+    delete d;
+    E *e = new E;
+    delete e;
+}
diff --git a/clang/test/PCH/Inputs/type_aware_destroying_new_delete.h 
b/clang/test/PCH/Inputs/type_aware_destroying_new_delete.h
new file mode 100644
index 0000000000000..42d609c0f5c26
--- /dev/null
+++ b/clang/test/PCH/Inputs/type_aware_destroying_new_delete.h
@@ -0,0 +1,52 @@
+
+namespace std {
+    struct destroying_delete_t { };
+    template <class T> struct type_identity {
+        using type = T;
+    };
+    typedef __SIZE_TYPE__ size_t;
+    enum class align_val_t : size_t;
+};
+
+struct A {
+    A();
+   void *operator new(std::size_t);
+   void operator delete(A*, std::destroying_delete_t);
+};
+
+struct B {
+    B();
+    void *operator new(std::type_identity<B>, std::size_t, std::align_val_t);
+    void operator delete(std::type_identity<B>, void*, std::size_t, 
std::align_val_t);
+};
+
+struct C {
+    C();
+    template <class T> void *operator new(std::type_identity<T>, std::size_t, 
std::align_val_t);
+    template <class T> void operator delete(std::type_identity<T>, void*, 
std::size_t, std::align_val_t);
+};
+
+struct D {
+    D();
+};
+void *operator new(std::type_identity<D>, std::size_t, std::align_val_t);
+void operator delete(std::type_identity<D>, void*, std::size_t, 
std::align_val_t);
+
+struct E {
+    E();
+};
+template <class T> void *operator new(std::type_identity<T>, std::size_t, 
std::align_val_t);
+template <class T> void operator delete(std::type_identity<T>, void*, 
std::size_t, std::align_val_t);
+
+void in_pch_tests() {
+  A* a = new A;
+  delete a;
+  B *b = new B;
+  delete b;
+  C *c = new C;
+  delete c;
+  D *d = new D;
+  delete d;
+  E *e = new E;
+  delete e;
+}
diff --git a/clang/test/PCH/type-aware-destroying-new-and-delete-pch.cpp 
b/clang/test/PCH/type-aware-destroying-new-and-delete-pch.cpp
new file mode 100644
index 0000000000000..d8f7f5dd50c78
--- /dev/null
+++ b/clang/test/PCH/type-aware-destroying-new-and-delete-pch.cpp
@@ -0,0 +1,27 @@
+// Test this without pch.
+// RUN: %clang_cc1 -x c++ -std=c++26 -include 
%S/Inputs/type_aware_destroying_new_delete.h -emit-llvm -o - %s
+
+// Test with pch.
+// RUN: %clang_cc1 -x c++ -std=c++26 -emit-pch -o %t 
%S/Inputs/type_aware_destroying_new_delete.h
+// RUN: %clang_cc1 -x c++ -std=c++26 -include-pch %t -emit-llvm -o - %s 
+
+// RUN: %clang_cc1 -x c++ -std=c++11 -emit-pch -fpch-instantiate-templates -o 
%t %S/Inputs/type_aware_destroying_new_delete.h
+// RUN: %clang_cc1 -x c++ -std=c++11 -include-pch %t -emit-llvm -o - %s
+
+
+static void call_in_pch_function(void) {
+    in_pch_tests();
+}
+
+void out_of_pch_tests() {
+    A* a = new A;
+    delete a;
+    B *b = new B;
+    delete b;
+    C *c = new C;
+    delete c;
+    D *d = new D;
+    delete d;
+    E *e = new E;
+    delete e;
+}

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to