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@a.h:* {{candidate function}} + // expected-note@a.h:* {{candidate function}} +#else + // expected-note@b.h:* {{candidate function}} + // expected-note@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 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits