https://github.com/balazske created https://github.com/llvm/llvm-project/pull/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. From 2bfad6f0fbb7a5757318c77ef76335986d23ab83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bal=C3=A1zs=20K=C3=A9ri?= <balazs.k...@ericsson.com> Date: Thu, 19 Oct 2023 16:27:24 +0200 Subject: [PATCH] [clang][ASTImporter] Fix import of SubstTemplateTypeParmType in return type of function. 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. --- clang/lib/AST/ASTImporter.cpp | 10 ++++++++++ clang/unittests/AST/ASTImporterTest.cpp | 23 ++++++++++++++++++++--- 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp index 628a2b2bbca3986..dbcd4e616ecf03c 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 f1f09a0be2b8d0c..21c24c2fcdc0007 100644 --- a/clang/unittests/AST/ASTImporterTest.cpp +++ b/clang/unittests/AST/ASTImporterTest.cpp @@ -6766,10 +6766,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); @@ -7208,6 +7211,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>(1); + )", + 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