Author: Balázs Kéri Date: 2023-11-24T14:35:10+01:00 New Revision: 3d8a9105d7e0e4baa744428e55d1c2462803118a
URL: https://github.com/llvm/llvm-project/commit/3d8a9105d7e0e4baa744428e55d1c2462803118a DIFF: https://github.com/llvm/llvm-project/commit/3d8a9105d7e0e4baa744428e55d1c2462803118a.diff LOG: [clang][ASTImporter] Fix import of SubstTemplateTypeParmType in return type of function. (#69724) Import of a function with `auto` return type that is expanded to a `SubstTemplateTypeParmType` could fail if the function itself is the template specialization where the parameter was replaced. Added: Modified: clang/lib/AST/ASTImporter.cpp clang/unittests/AST/ASTImporterTest.cpp Removed: ################################################################################ diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp index c4e931e220f69b5..3dc33c10af11edf 100644 --- a/clang/lib/AST/ASTImporter.cpp +++ b/clang/lib/AST/ASTImporter.cpp @@ -3513,6 +3513,14 @@ class IsTypeDeclaredInsideVisitor return {}; } + std::optional<bool> + VisitSubstTemplateTypeParmType(const SubstTemplateTypeParmType *T) { + // The "associated declaration" can be the same as ParentDC. + if (isAncestorDeclContextOf(ParentDC, T->getAssociatedDecl())) + return true; + return {}; + } + std::optional<bool> VisitConstantArrayType(const ConstantArrayType *T) { if (T->getSizeExpr() && isAncestorDeclContextOf(ParentDC, T->getSizeExpr())) return true; @@ -3573,6 +3581,8 @@ class IsTypeDeclaredInsideVisitor }; } // namespace +/// This function checks if the function has 'auto' return type that contains +/// a reference (in any way) to a declaration inside the same function. bool ASTNodeImporter::hasAutoReturnTypeDeclaredInside(FunctionDecl *D) { QualType FromTy = D->getType(); const auto *FromFPT = FromTy->getAs<FunctionProtoType>(); diff --git a/clang/unittests/AST/ASTImporterTest.cpp b/clang/unittests/AST/ASTImporterTest.cpp index 5f4d8d040772cb1..902b740a5106c0d 100644 --- a/clang/unittests/AST/ASTImporterTest.cpp +++ b/clang/unittests/AST/ASTImporterTest.cpp @@ -6790,10 +6790,13 @@ TEST_P(ASTImporterOptionSpecificTestBase, } struct ImportAutoFunctions : ASTImporterOptionSpecificTestBase { - void testImport(llvm::StringRef Code, clang::TestLanguage Lang = Lang_CXX14) { + void testImport(llvm::StringRef Code, clang::TestLanguage Lang = Lang_CXX14, + bool FindLast = false) { Decl *FromTU = getTuDecl(Code, Lang, "input0.cc"); - FunctionDecl *From = FirstDeclMatcher<FunctionDecl>().match( - FromTU, functionDecl(hasName("foo"))); + FunctionDecl *From = FindLast ? LastDeclMatcher<FunctionDecl>().match( + FromTU, functionDecl(hasName("foo"))) + : FirstDeclMatcher<FunctionDecl>().match( + FromTU, functionDecl(hasName("foo"))); FunctionDecl *To = Import(From, Lang); EXPECT_TRUE(To); @@ -7232,6 +7235,20 @@ TEST_P(ImportAutoFunctions, ReturnWithTypeInSwitch) { Lang_CXX17); } +TEST_P(ImportAutoFunctions, ReturnWithAutoTemplateType) { + testImport( + R"( + template<class T> + struct S {}; + template<class T> + auto foo() { + return S<T>{}; + } + auto a = foo<int>(); + )", + Lang_CXX14, /*FindLast=*/true); +} + struct ImportSourceLocations : ASTImporterOptionSpecificTestBase {}; TEST_P(ImportSourceLocations, PreserveFileIDTreeStructure) { _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits