This revision was landed with ongoing or failed builds. This revision was automatically updated to reflect the committed changes. martong marked an inline comment as done. Closed by commit rG1e14588d0f68: [Clang][Sema] Attempt to fix CTAD faulty copy of non-local typedefs (authored by martong).
Changed prior to commit: https://reviews.llvm.org/D92101?vs=308922&id=309199#toc Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D92101/new/ 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 @@ -5998,6 +5998,77 @@ 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, ); Index: clang/lib/Sema/SemaTemplate.cpp =================================================================== --- clang/lib/Sema/SemaTemplate.cpp +++ clang/lib/Sema/SemaTemplate.cpp @@ -2077,27 +2077,28 @@ 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());
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits