[clang] 9ab5f76 - Support for merging UsingPackDecls across modules.

Richard Smith via cfe-commits cfe-commits at lists.llvm.org
Thu Jul 1 18:43:59 PDT 2021


Author: Richard Smith
Date: 2021-07-01T18:43:49-07:00
New Revision: 9ab5f761176c376c0a117c53f0f111fed1bcc842

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

LOG: Support for merging UsingPackDecls across modules.

Fixes a false-positive error if the same std::variant<...> type is
instantiated across multiple modules.

Added: 
    

Modified: 
    clang/lib/Serialization/ASTReaderDecl.cpp
    clang/test/Modules/Inputs/merge-using-decls/a.h
    clang/test/Modules/Inputs/merge-using-decls/b.h
    clang/test/Modules/merge-using-decls.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp
index 1d9bae5d3129c..ff79f91e5db1b 100644
--- a/clang/lib/Serialization/ASTReaderDecl.cpp
+++ b/clang/lib/Serialization/ASTReaderDecl.cpp
@@ -3067,7 +3067,7 @@ static bool hasSameOverloadableAttrs(const FunctionDecl *A,
   return true;
 }
 
-/// Determine whether the two declarations refer to the same entity.pr
+/// Determine whether the two declarations refer to the same entity.
 static bool isSameEntity(NamedDecl *X, NamedDecl *Y) {
   assert(X->getDeclName() == Y->getDeclName() && "Declaration name mismatch!");
 
@@ -3261,10 +3261,19 @@ static bool isSameEntity(NamedDecl *X, NamedDecl *Y) {
     return isSameQualifier(UX->getQualifier(), UY->getQualifier()) &&
            UX->isAccessDeclaration() == UY->isAccessDeclaration();
   }
-  if (const auto *UX = dyn_cast<UnresolvedUsingTypenameDecl>(X))
+  if (const auto *UX = dyn_cast<UnresolvedUsingTypenameDecl>(X)) {
     return isSameQualifier(
         UX->getQualifier(),
         cast<UnresolvedUsingTypenameDecl>(Y)->getQualifier());
+  }
+
+  // Using-pack declarations are only created by instantiation, and match if
+  // they're instantiated from matching UnresolvedUsing...Decls.
+  if (const auto *UX = dyn_cast<UsingPackDecl>(X)) {
+    return declaresSameEntity(
+        UX->getInstantiatedFromUsingDecl(),
+        cast<UsingPackDecl>(Y)->getInstantiatedFromUsingDecl());
+  }
 
   // Namespace alias definitions with the same target match.
   if (const auto *NAX = dyn_cast<NamespaceAliasDecl>(X)) {

diff  --git a/clang/test/Modules/Inputs/merge-using-decls/a.h b/clang/test/Modules/Inputs/merge-using-decls/a.h
index 0fe0067bf23c4..2469cbd7601fe 100644
--- a/clang/test/Modules/Inputs/merge-using-decls/a.h
+++ b/clang/test/Modules/Inputs/merge-using-decls/a.h
@@ -1,6 +1,7 @@
 struct X {
   int v;
   typedef int t;
+  void f(X);
 };
 
 struct YA {
@@ -8,6 +9,10 @@ struct YA {
   typedef int type;
 };
 
+struct Z {
+  void f(Z);
+};
+
 template<typename T> struct C : X, T {
   using T::value;
   using typename T::type;
@@ -41,3 +46,10 @@ typedef C<YA>::type I;
 typedef D<YA>::type I;
 typedef E<YA>::type I;
 typedef F<YA>::type I;
+
+#if __cplusplus >= 201702L
+template<typename ...T> struct G : T... {
+  using T::f...;
+};
+using Q = decltype(G<X, Z>());
+#endif

diff  --git a/clang/test/Modules/Inputs/merge-using-decls/b.h b/clang/test/Modules/Inputs/merge-using-decls/b.h
index 5d112ffbfe96f..be9bf240ccebf 100644
--- a/clang/test/Modules/Inputs/merge-using-decls/b.h
+++ b/clang/test/Modules/Inputs/merge-using-decls/b.h
@@ -1,6 +1,7 @@
 struct X {
   int v;
   typedef int t;
+  void f(X);
 };
 
 struct YB {
@@ -14,6 +15,10 @@ struct YBRev {
   int type;
 };
 
+struct Z {
+  void f(Z);
+};
+
 template<typename T> struct C : X, T {
   using T::value;
   using typename T::type;
@@ -54,3 +59,10 @@ typedef E<YB>::type I;
 #endif
 
 typedef F<YB>::type I;
+
+#if __cplusplus >= 201702L
+template<typename ...T> struct G : T... {
+  using T::f...;
+};
+using Q = decltype(G<X, Z>());
+#endif

diff  --git a/clang/test/Modules/merge-using-decls.cpp b/clang/test/Modules/merge-using-decls.cpp
index 1ec9a9a17bdee..e3bf977f05449 100644
--- a/clang/test/Modules/merge-using-decls.cpp
+++ b/clang/test/Modules/merge-using-decls.cpp
@@ -2,9 +2,11 @@
 // RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -x c++ -I%S/Inputs/merge-using-decls -verify %s -DORDER=1
 // RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -x c++ -I%S/Inputs/merge-using-decls -verify -std=c++98 %s -DORDER=1
 // RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -x c++ -I%S/Inputs/merge-using-decls -verify -std=c++11 %s -DORDER=1
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -x c++ -I%S/Inputs/merge-using-decls -verify -std=c++17 %s -DORDER=1
 // RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -x c++ -I%S/Inputs/merge-using-decls -verify %s -DORDER=2
 // RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -x c++ -I%S/Inputs/merge-using-decls -verify -std=c++98 %s -DORDER=2
 // RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -x c++ -I%S/Inputs/merge-using-decls -verify -std=c++11 %s -DORDER=2
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -x c++ -I%S/Inputs/merge-using-decls -verify -std=c++17 %s -DORDER=2
 
 #if ORDER == 1
 #include "a.h"
@@ -39,6 +41,19 @@ template int UseAll<YA>();
 template int UseAll<YB>();
 template int UseAll<Y>();
 
+#if __cplusplus >= 201702L
+void use_g(Q q) {
+  q.f(q); // expected-error {{ambiguous}}
+#if ORDER == 1
+  // expected-note at a.h:* {{candidate function}}
+  // expected-note at a.h:* {{candidate function}}
+#else
+  // expected-note at b.h:* {{candidate function}}
+  // expected-note at b.h:* {{candidate function}}
+#endif
+}
+#endif
+
 // Which of these two sets of diagnostics is chosen is not important. It's OK
 // if this varies with ORDER, but it must be consistent across runs.
 #if ORDER == 1


        


More information about the cfe-commits mailing list