[clang] 1b59809 - [C++20] [Modules] Don't create duplicated deduction guides for duplicated classes

Chuanqi Xu via cfe-commits cfe-commits at lists.llvm.org
Tue Mar 28 02:51:59 PDT 2023


Author: Chuanqi Xu
Date: 2023-03-28T17:51:38+08:00
New Revision: 1b5980997bc03659a41329c3dff96ff274e13d85

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

LOG: [C++20] [Modules] Don't create duplicated deduction guides for duplicated classes

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

Within C++20 modules, we may have multiple same constructors in
multiple same RecordDecls. And it doesn't make sense naturally to create
duplicated deduction guides for the duplicated constructors.

Added: 
    clang/test/Modules/pr56916.cppm

Modified: 
    clang/docs/StandardCPlusPlusModules.rst
    clang/lib/Sema/SemaTemplate.cpp
    clang/test/Modules/pr61317.cppm

Removed: 
    


################################################################################
diff  --git a/clang/docs/StandardCPlusPlusModules.rst b/clang/docs/StandardCPlusPlusModules.rst
index ab34ba03ba14c..e14bbe4e1c655 100644
--- a/clang/docs/StandardCPlusPlusModules.rst
+++ b/clang/docs/StandardCPlusPlusModules.rst
@@ -660,26 +660,6 @@ the orders matter here in the case.
 
 This is tracked in: https://github.com/llvm/llvm-project/issues/61465
 
-Ambiguous deduction guide
-~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Currently, when we call deduction guides in global module fragment,
-we may get incorrect diagnosing message like: `ambiguous deduction`.
-
-So if we're using deduction guide from global module fragment, we probably need to write:
-
-.. code-block:: c++
-
-  std::lock_guard<std::mutex> lk(mutex);
-
-instead of
-
-.. code-block:: c++
-
-  std::lock_guard lk(mutex);
-
-This is tracked in: https://github.com/llvm/llvm-project/issues/56916
-
 Ignored PreferredName Attribute
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 

diff  --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index c3338e4eaed28..befc1e73c4f35 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -2601,13 +2601,21 @@ void Sema::DeclareImplicitDeductionGuides(TemplateDecl *Template,
   // FIXME: Skip constructors for which deduction must necessarily fail (those
   // for which some class template parameter without a default argument never
   // appears in a deduced context).
+  llvm::SmallPtrSet<NamedDecl *, 8> ProcessedCtors;
   bool AddedAny = false;
   for (NamedDecl *D : LookupConstructors(Transform.Primary)) {
     D = D->getUnderlyingDecl();
     if (D->isInvalidDecl() || D->isImplicit())
       continue;
+
     D = cast<NamedDecl>(D->getCanonicalDecl());
 
+    // Within C++20 modules, we may have multiple same constructors in
+    // multiple same RecordDecls. And it doesn't make sense to create
+    // duplicated deduction guides for the duplicated constructors.
+    if (ProcessedCtors.count(D))
+      continue;
+
     auto *FTD = dyn_cast<FunctionTemplateDecl>(D);
     auto *CD =
         dyn_cast_or_null<CXXConstructorDecl>(FTD ? FTD->getTemplatedDecl() : D);
@@ -2622,6 +2630,7 @@ void Sema::DeclareImplicitDeductionGuides(TemplateDecl *Template,
         }))
       continue;
 
+    ProcessedCtors.insert(D);
     Transform.transformConstructor(FTD, CD);
     AddedAny = true;
   }

diff  --git a/clang/test/Modules/pr56916.cppm b/clang/test/Modules/pr56916.cppm
new file mode 100644
index 0000000000000..a8b49f0f6ff19
--- /dev/null
+++ b/clang/test/Modules/pr56916.cppm
@@ -0,0 +1,41 @@
+// RUN: rm -rf %t
+// RUN: mkdir %t
+// RUN: split-file %s %t
+//
+// RUN: %clang_cc1 -std=c++20 %t/A.cppm -emit-module-interface -o %t/M-A.pcm
+// RUN: %clang_cc1 -std=c++20 %t/B.cppm -emit-module-interface -o %t/M-B.pcm
+// RUN: %clang_cc1 -std=c++20 %t/M.cppm -emit-module-interface -o %t/M.pcm \
+// RUN:     -fprebuilt-module-path=%t
+// RUN: %clang_cc1 -std=c++20 %t/Use.cpp -fmodule-file=M=%t/M.pcm -fsyntax-only \
+// RUN:     -verify
+
+//--- foo.h
+template <typename T>
+class Templ {
+public:
+    Templ(T a) {}
+};
+
+//--- A.cppm
+module;
+#include "foo.h"
+export module M:A;
+export using ::Templ;
+
+//--- B.cppm
+module;
+#include "foo.h"
+export module M:B;
+
+//--- M.cppm
+export module M;
+export import :A;
+export import :B;
+
+//--- Use.cpp
+// expected-no-diagnostics
+import M;
+
+void func() {
+    Templ t(5);
+}

diff  --git a/clang/test/Modules/pr61317.cppm b/clang/test/Modules/pr61317.cppm
index 4b9c1a3e97eab..4b54d26dc5a63 100644
--- a/clang/test/Modules/pr61317.cppm
+++ b/clang/test/Modules/pr61317.cppm
@@ -13,7 +13,7 @@
 #define _FOO
 
 template <typename T> struct Foo {
-  Foo(T) {}
+  Foo(T f) {}
 };
 
 template <typename T> Foo(T&) -> Foo<T>;
@@ -24,6 +24,16 @@ struct Bar {
   void baz() const {}
 };
 
+template <typename T> struct Foo2 {
+  Foo2(T f) {}
+};
+
+struct Bar2 {
+  template <typename T>
+    requires requires { Foo2{T()}; }
+  void baz2() const {}
+};
+
 #endif
 
 //--- A.cppm
@@ -32,6 +42,7 @@ module;
 export module A;
 export using ::Foo;
 export using ::Bar;
+export using ::Bar2;
 
 //--- B.cppm
 module;
@@ -46,4 +57,7 @@ import B;
 void use() {
   Bar _; 
   _.baz<int>();
+
+  Bar2 __; 
+  __.baz2<int>();
 }


        


More information about the cfe-commits mailing list