[PATCH] D92101: [Clang][Sema] Attempt to fix CTAD faulty copy of non-local typedefs
Gabor Marton via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Wed Nov 25 07:31:44 PST 2020
martong created this revision.
martong added a reviewer: rsmith.
Herald added subscribers: cfe-commits, gamesh411, Szelethus, dkrupp, rnkovacs.
Herald added a reviewer: shafik.
Herald added a project: clang.
martong requested review of this revision.
http://lists.llvm.org/pipermail/cfe-dev/2020-November/067252.html
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D92101
Files:
clang/lib/Sema/SemaTemplate.cpp
clang/unittests/AST/ASTImporterTest.cpp
Index: clang/unittests/AST/ASTImporterTest.cpp
===================================================================
--- clang/unittests/AST/ASTImporterTest.cpp
+++ clang/unittests/AST/ASTImporterTest.cpp
@@ -5865,6 +5865,56 @@
EXPECT_EQ(Record, CompletedTags.front());
}
+// FIXME Move these tests out of ASTImporterTest. For that we need to factor
+// out the ASTImporter specific pars from ASTImporterOptionSpecificTestBase
+// into a new test Fixture. Then we should lift up this Fixture to its own
+// implementation file and only then could we reuse the Fixture in other AST
+// unitttests.
+struct CTAD : ASTImporterOptionSpecificTestBase {};
+
+TEST_P(CTAD, DeductionGuideShouldReferToANonLocalTypedef) {
+ Decl *TU = getTuDecl(
+ R"(
+ typedef int U;
+ template <typename T> struct A {
+ A(U, T);
+ };
+ A a{(int)0, (int)0};
+ )",
+ Lang_CXX17, "input.cc");
+ TU->dump();
+ auto *Guide = FirstDeclMatcher<CXXDeductionGuideDecl>().match(
+ TU, cxxDeductionGuideDecl());
+ auto *Typedef = FirstDeclMatcher<TypedefNameDecl>().match(
+ TU, typedefNameDecl(hasName("U")));
+ ParmVarDecl *Param = Guide->getParamDecl(0);
+ // The type of the first param (which is a typedef) should match the typedef
+ // in the global scope.
+ EXPECT_EQ(Param->getType()->getAs<TypedefType>()->getDecl(), Typedef);
+}
+
+TEST_P(CTAD, DeductionGuideShouldCopyALocalTypedef) {
+ Decl *TU = getTuDecl(
+ R"(
+ template <typename T> struct A {
+ typedef T U;
+ A(U, T);
+ };
+ A a{(int)0, (int)0};
+ )",
+ Lang_CXX17, "input.cc");
+ TU->dump();
+ auto *Guide = FirstDeclMatcher<CXXDeductionGuideDecl>().match(
+ TU, cxxDeductionGuideDecl());
+ auto *Typedef = FirstDeclMatcher<TypedefNameDecl>().match(
+ TU, typedefNameDecl(hasName("U")));
+ ParmVarDecl *Param = Guide->getParamDecl(0);
+ EXPECT_NE(Param->getType()->getAs<TypedefType>()->getDecl(), Typedef);
+}
+
+INSTANTIATE_TEST_CASE_P(ParameterizedTests, CTAD,
+ DefaultTestValuesForRunOptions, );
+
INSTANTIATE_TEST_CASE_P(ParameterizedTests, ASTImporterLookupTableTest,
DefaultTestValuesForRunOptions, );
Index: clang/lib/Sema/SemaTemplate.cpp
===================================================================
--- clang/lib/Sema/SemaTemplate.cpp
+++ clang/lib/Sema/SemaTemplate.cpp
@@ -2350,6 +2350,15 @@
ParmVarDecl *OldParam, MultiLevelTemplateArgumentList &Args,
llvm::SmallVectorImpl<TypedefNameDecl *> &MaterializedTypedefs) {
TypeSourceInfo *OldDI = OldParam->getTypeSourceInfo();
+
+ if (auto *OldTypedefT = OldParam->getType()->getAs<TypedefType>()) {
+ TypedefNameDecl *OldTypedefDecl = OldTypedefT->getDecl();
+ auto *CD = cast<CXXConstructorDecl>(OldParam->getDeclContext());
+ // If the typedef is not a local typedef, then skip the transform.
+ if (OldTypedefDecl->getDeclContext() != CD->getDeclContext())
+ return OldParam;
+ }
+
TypeSourceInfo *NewDI;
if (auto PackTL = OldDI->getTypeLoc().getAs<PackExpansionTypeLoc>()) {
// Expand out the one and only element in each inner pack.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D92101.307611.patch
Type: text/x-patch
Size: 3185 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20201125/f42fbc55/attachment-0001.bin>
More information about the cfe-commits
mailing list