[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