[clang] a68638b - [C++20] [Modules] [Reduced BMI] Handling Deduction Guide in reduced BMI

Chuanqi Xu via cfe-commits cfe-commits at lists.llvm.org
Sun Jun 2 23:59:56 PDT 2024


Author: Chuanqi Xu
Date: 2024-06-03T14:59:23+08:00
New Revision: a68638bf6a6a5cb60947753ccaf7d1de80f6c89e

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

LOG: [C++20] [Modules] [Reduced BMI] Handling Deduction Guide in reduced BMI
carefully

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

The direct pattern of the issue is that, in a reduced BMI, we're going
to wrtie a class but we didn't write the deduction guide. Although we
handled deduction guide, but we tried to record the found deduction
guide from `noload_lookup` directly.

It is slightly problematic if the found deduction guide is from AST.
e.g.,

```
module;
export module m;
import xxx; // Also contains the class and the deduction guide
...
```

Then when we writes the class in the current file, we tried to record
the deduction guide, but `noload_lookup` returns the deduction guide
from the AST file then we didn't record the local deduction guide. Then
mismatch happens.

To mitiagte the problem, we tried to record the canonical declaration
for the decution guide.

Added: 
    clang/test/Modules/pr93859.cppm

Modified: 
    clang/lib/Serialization/ASTWriterDecl.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/Serialization/ASTWriterDecl.cpp b/clang/lib/Serialization/ASTWriterDecl.cpp
index bbd16dbdb8fff..5a6ab4408eb2b 100644
--- a/clang/lib/Serialization/ASTWriterDecl.cpp
+++ b/clang/lib/Serialization/ASTWriterDecl.cpp
@@ -1733,7 +1733,7 @@ void ASTDeclWriter::VisitClassTemplateDecl(ClassTemplateDecl *D) {
   if (Writer.isGeneratingReducedBMI()) {
     auto Name = Context.DeclarationNames.getCXXDeductionGuideName(D);
     for (auto *DG : D->getDeclContext()->noload_lookup(Name))
-      Writer.GetDeclRef(DG);
+      Writer.GetDeclRef(DG->getCanonicalDecl());
   }
 
   Code = serialization::DECL_CLASS_TEMPLATE;

diff  --git a/clang/test/Modules/pr93859.cppm b/clang/test/Modules/pr93859.cppm
new file mode 100644
index 0000000000000..d1d45bb975308
--- /dev/null
+++ b/clang/test/Modules/pr93859.cppm
@@ -0,0 +1,146 @@
+// Reduced from https://github.com/llvm/llvm-project/issues/93859
+//
+// RUN: rm -rf %t
+// RUN: mkdir -p %t
+// RUN: split-file %s %t
+//
+// RUN: %clang_cc1 -std=c++20 %t/reduced_std.cppm -emit-reduced-module-interface -o %t/reduced_std.pcm
+// RUN: %clang_cc1 -std=c++20 %t/Misc.cppm -emit-reduced-module-interface -o %t/Misc.pcm \
+// RUN:     -fprebuilt-module-path=%t
+// RUN: %clang_cc1 -std=c++20 %t/Instance.cppm -emit-reduced-module-interface -o %t/Instance.pcm \
+// RUN:     -fprebuilt-module-path=%t
+// RUN: %clang_cc1 -std=c++20 %t/Device.cppm -emit-reduced-module-interface -o %t/Device.pcm \
+// RUN:     -fprebuilt-module-path=%t
+// RUN: %clang_cc1 -std=c++20 %t/Overlay.cppm -emit-reduced-module-interface -o %t/Overlay.pcm \
+// RUN:     -fprebuilt-module-path=%t
+// RUN: %clang_cc1 -std=c++20 %t/App.cppm -emit-module-interface -o /dev/null \
+// RUN:     -fexperimental-modules-reduced-bmi -fmodule-output=%t/App.pcm \
+// RUN:     -fprebuilt-module-path=%t
+// RUN: %clang_cc1 -std=c++20 %t/test.cc -fsyntax-only -verify \
+// RUN:     -fprebuilt-module-path=%t
+
+//--- header.h
+namespace std {
+
+template <class _T1, class _T2>
+struct pair
+{
+  _T1 first;
+  _T2 second;
+
+  constexpr pair()
+      : first(), second() {}
+
+  constexpr pair(_T1 const& __t1, _T2 const& __t2)
+      : first(__t1), second(__t2) {}
+};
+
+template <class _T1, class _T2>
+pair(_T1, _T2) -> pair<_T1, _T2>;
+
+template <class _Tp>
+class __tree_const_iterator {
+public:
+  template <class>
+  friend class __tree;
+};
+
+template <class _Tp>
+class __tree {
+public:
+  typedef _Tp value_type;
+  typedef __tree_const_iterator<value_type> const_iterator;
+
+  template <class, class, class, class>
+  friend class map;
+};
+
+template <class _Key>
+class set {
+public:
+  typedef __tree<_Key> __base;
+
+  typedef typename __base::const_iterator iterator;
+
+  set() {}
+
+  pair<iterator, bool>
+  insert(const _Key& __v);
+};
+
+template <class _InputIterator, class _OutputIterator>
+inline constexpr _OutputIterator
+copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result) {
+  return pair{__first, __last}.second;
+}
+
+}
+
+//--- reduced_std.cppm
+module;
+#include "header.h"
+export module reduced_std;
+
+export namespace std {
+    using std::set;
+    using std::copy;
+}
+
+//--- Misc.cppm
+export module Misc;
+import reduced_std;
+
+export void check_result(int res) {
+    std::set<char> extensions;
+    extensions.insert('f');
+}
+
+//--- Instance.cppm
+export module Instance;
+import reduced_std;
+
+export class Instance {
+public:
+    Instance() {
+        std::set<const char*> extensions;
+        extensions.insert("foo");
+    }
+};
+
+//--- Device.cppm
+export module Device;
+import reduced_std;
+import Instance;
+import Misc;
+
+std::set<int> wtf_set;
+
+//--- Overlay.cppm
+export module Overlay;
+
+import reduced_std;
+import Device;
+
+void overlay_vector_use() {
+    std::set<int> nums;
+    nums.insert(1);
+}
+
+//--- App.cppm
+module;
+#include "header.h"
+export module App;
+import Overlay;
+
+std::set<float> fs;
+
+//--- test.cc
+// expected-no-diagnostics
+import reduced_std;
+import App;
+
+void render() {
+    unsigned *oidxs = nullptr;
+    unsigned idxs[] = {0, 1, 2, 0, 2, 3};
+    std::copy(idxs, idxs + 6, oidxs);
+}


        


More information about the cfe-commits mailing list