[clang] ee1be28 - [C++20] [Modules] Make placement allocation functions always visible

Chuanqi Xu via cfe-commits cfe-commits at lists.llvm.org
Sun Jan 8 18:41:13 PST 2023


Author: Chuanqi Xu
Date: 2023-01-09T10:40:23+08:00
New Revision: ee1be282241b1253847e663af000f7082b7f03a3

URL: https://github.com/llvm/llvm-project/commit/ee1be282241b1253847e663af000f7082b7f03a3
DIFF: https://github.com/llvm/llvm-project/commit/ee1be282241b1253847e663af000f7082b7f03a3.diff

LOG: [C++20] [Modules] Make placement allocation functions always visible

Close https://github.com/llvm/llvm-project/issues/59601.

This is actually a workaround for the issue. See the comments and the
test for example. The proper fix should make the placement allocation
functions acceptable based on the context. But it is harder and more
complex on the one side. On the other side, such workaround won't be too
bad in practice since users rarely call the placement allocation
functions directly.

So personally I prefer to address such problems in the simpler way.

Reviewed By: royjacobson

Differential Revision: https://reviews.llvm.org/D141023

Added: 
    clang/test/Modules/placement-new-reachable.cpp

Modified: 
    clang/lib/Sema/SemaLookup.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp
index 97b3c97a9e51e..4ec8a373ed47b 100644
--- a/clang/lib/Sema/SemaLookup.cpp
+++ b/clang/lib/Sema/SemaLookup.cpp
@@ -2099,6 +2099,22 @@ bool LookupResult::isAvailableForLookup(Sema &SemaRef, NamedDecl *ND) {
   if (auto *DeductionGuide = ND->getDeclName().getCXXDeductionGuideTemplate())
     return SemaRef.hasReachableDefinition(DeductionGuide);
 
+  // FIXME: The lookup for allocation function is a standalone process.
+  // (We can find the logics in Sema::FindAllocationFunctions)
+  //
+  // Such structure makes it a problem when we instantiate a template
+  // declaration using placement allocation function if the placement
+  // allocation function is invisible.
+  // (See https://github.com/llvm/llvm-project/issues/59601)
+  //
+  // Here we workaround it by making the placement allocation functions
+  // always acceptable. The downside is that we can't diagnose the direct
+  // use of the invisible placement allocation functions. (Although such uses
+  // should be rare).
+  if (auto *FD = dyn_cast<FunctionDecl>(ND);
+      FD && FD->isReservedGlobalPlacementOperator())
+    return true;
+
   auto *DC = ND->getDeclContext();
   // If ND is not visible and it is at namespace scope, it shouldn't be found
   // by name lookup.

diff  --git a/clang/test/Modules/placement-new-reachable.cpp b/clang/test/Modules/placement-new-reachable.cpp
new file mode 100644
index 0000000000000..29263173d78f4
--- /dev/null
+++ b/clang/test/Modules/placement-new-reachable.cpp
@@ -0,0 +1,39 @@
+// RUN: rm -rf %t
+// RUN: mkdir -p %t
+// RUN: split-file %s %t
+//
+// RUN: %clang_cc1 -std=c++20 %t/A.cppm -emit-module-interface -o %t/A.pcm
+// RUN: %clang_cc1 -std=c++20 %t/Use.cpp -fprebuilt-module-path=%t -fsyntax-only -verify
+
+//--- placement.h
+namespace std {
+  using size_t = decltype(sizeof(0));
+}
+void *operator new(std::size_t, void *p) { return p; }
+
+//--- A.cppm
+module;
+#include "placement.h"
+export module A;
+export template<class T>
+struct A {
+    A(void *p) : ptr(new (p) T(43)) {}
+private:
+    void *ptr;
+};
+
+export struct B {
+    B(void *p) : ptr(new (p) int(43)) {}
+private:
+    void *ptr;
+};
+
+//--- Use.cpp
+// expected-no-diagnostics
+import A;
+void bar(int *);
+void foo(void *ptr) {
+    A<int>(nullptr); // Good. It should be OK to construct A.
+    void *p = ::operator new(sizeof(int), ptr); // Bad. The function shouldn't be visible here.
+    void *q = new (ptr) int(43); // Good. We don't call the placement allocation function directly.
+}


        


More information about the cfe-commits mailing list