Skip to content

Commit

Permalink
[clang][ASTImporter] Fix import of SubstTemplateTypeParmType in retur…
Browse files Browse the repository at this point in the history
…n 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.
  • Loading branch information
balazske committed Nov 24, 2023
1 parent dc9787c commit 3d8a910
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 3 deletions.
10 changes: 10 additions & 0 deletions clang/lib/AST/ASTImporter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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>();
Expand Down
23 changes: 20 additions & 3 deletions clang/unittests/AST/ASTImporterTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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) {
Expand Down

0 comments on commit 3d8a910

Please sign in to comment.