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