[llvm-branch-commits] [clang] 1e14588 - [Clang][Sema] Attempt to fix CTAD faulty copy of non-local typedefs
Gabor Marton via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Thu Dec 3 02:40:47 PST 2020
Author: Gabor Marton
Date: 2020-12-03T11:35:47+01:00
New Revision: 1e14588d0f6845976e774c87a18a84a0f7b61015
URL: https://github.com/llvm/llvm-project/commit/1e14588d0f6845976e774c87a18a84a0f7b61015
DIFF: https://github.com/llvm/llvm-project/commit/1e14588d0f6845976e774c87a18a84a0f7b61015.diff
LOG: [Clang][Sema] Attempt to fix CTAD faulty copy of non-local typedefs
http://lists.llvm.org/pipermail/cfe-dev/2020-November/067252.html
Differential Revision: https://reviews.llvm.org/D92101
Added:
Modified:
clang/lib/Sema/SemaTemplate.cpp
clang/unittests/AST/ASTImporterTest.cpp
Removed:
################################################################################
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 5b321bb74400..5710f9e3daad 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -2077,27 +2077,28 @@ class ExtractTypeForDeductionGuide
QualType TransformTypedefType(TypeLocBuilder &TLB, TypedefTypeLoc TL) {
ASTContext &Context = SemaRef.getASTContext();
TypedefNameDecl *OrigDecl = TL.getTypedefNameDecl();
- TypeLocBuilder InnerTLB;
- QualType Transformed =
- TransformType(InnerTLB, OrigDecl->getTypeSourceInfo()->getTypeLoc());
- TypeSourceInfo *TSI =
- TransformType(InnerTLB.getTypeSourceInfo(Context, Transformed));
-
- TypedefNameDecl *Decl = nullptr;
-
- if (isa<TypeAliasDecl>(OrigDecl))
- Decl = TypeAliasDecl::Create(
- Context, Context.getTranslationUnitDecl(), OrigDecl->getBeginLoc(),
- OrigDecl->getLocation(), OrigDecl->getIdentifier(), TSI);
- else {
- assert(isa<TypedefDecl>(OrigDecl) && "Not a Type alias or typedef");
- Decl = TypedefDecl::Create(
- Context, Context.getTranslationUnitDecl(), OrigDecl->getBeginLoc(),
- OrigDecl->getLocation(), OrigDecl->getIdentifier(), TSI);
+ TypedefNameDecl *Decl = OrigDecl;
+ // Transform the underlying type of the typedef and clone the Decl only if
+ // the typedef has a dependent context.
+ if (OrigDecl->getDeclContext()->isDependentContext()) {
+ TypeLocBuilder InnerTLB;
+ QualType Transformed =
+ TransformType(InnerTLB, OrigDecl->getTypeSourceInfo()->getTypeLoc());
+ TypeSourceInfo *TSI =
+ TransformType(InnerTLB.getTypeSourceInfo(Context, Transformed));
+ if (isa<TypeAliasDecl>(OrigDecl))
+ Decl = TypeAliasDecl::Create(
+ Context, Context.getTranslationUnitDecl(), OrigDecl->getBeginLoc(),
+ OrigDecl->getLocation(), OrigDecl->getIdentifier(), TSI);
+ else {
+ assert(isa<TypedefDecl>(OrigDecl) && "Not a Type alias or typedef");
+ Decl = TypedefDecl::Create(
+ Context, Context.getTranslationUnitDecl(), OrigDecl->getBeginLoc(),
+ OrigDecl->getLocation(), OrigDecl->getIdentifier(), TSI);
+ }
+ MaterializedTypedefs.push_back(Decl);
}
- MaterializedTypedefs.push_back(Decl);
-
QualType TDTy = Context.getTypedefType(Decl);
TypedefTypeLoc TypedefTL = TLB.push<TypedefTypeLoc>(TDTy);
TypedefTL.setNameLoc(TL.getNameLoc());
diff --git a/clang/unittests/AST/ASTImporterTest.cpp b/clang/unittests/AST/ASTImporterTest.cpp
index 7e56b3ed501f..e4c73a832a14 100644
--- a/clang/unittests/AST/ASTImporterTest.cpp
+++ b/clang/unittests/AST/ASTImporterTest.cpp
@@ -5998,6 +5998,77 @@ TEST_P(ImportFunctions, CTADUserDefinedExplicit) {
EXPECT_TRUE(ToD->isExplicit());
}
+// 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");
+ 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, DeductionGuideShouldReferToANonLocalTypedefInParamPtr) {
+ 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");
+ auto *Guide = FirstDeclMatcher<CXXDeductionGuideDecl>().match(
+ TU, cxxDeductionGuideDecl());
+ auto *Typedef = FirstDeclMatcher<TypedefNameDecl>().match(
+ TU, typedefNameDecl(hasName("U")));
+ ParmVarDecl *Param = Guide->getParamDecl(0);
+ EXPECT_EQ(Param->getType()
+ ->getAs<PointerType>()
+ ->getPointeeType()
+ ->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");
+ 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, );
More information about the llvm-branch-commits
mailing list