Skip to content

Commit 3d8a910

Browse files
authored
[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.
1 parent dc9787c commit 3d8a910

File tree

2 files changed

+30
-3
lines changed

2 files changed

+30
-3
lines changed

clang/lib/AST/ASTImporter.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3513,6 +3513,14 @@ class IsTypeDeclaredInsideVisitor
35133513
return {};
35143514
}
35153515

3516+
std::optional<bool>
3517+
VisitSubstTemplateTypeParmType(const SubstTemplateTypeParmType *T) {
3518+
// The "associated declaration" can be the same as ParentDC.
3519+
if (isAncestorDeclContextOf(ParentDC, T->getAssociatedDecl()))
3520+
return true;
3521+
return {};
3522+
}
3523+
35163524
std::optional<bool> VisitConstantArrayType(const ConstantArrayType *T) {
35173525
if (T->getSizeExpr() && isAncestorDeclContextOf(ParentDC, T->getSizeExpr()))
35183526
return true;
@@ -3573,6 +3581,8 @@ class IsTypeDeclaredInsideVisitor
35733581
};
35743582
} // namespace
35753583

3584+
/// This function checks if the function has 'auto' return type that contains
3585+
/// a reference (in any way) to a declaration inside the same function.
35763586
bool ASTNodeImporter::hasAutoReturnTypeDeclaredInside(FunctionDecl *D) {
35773587
QualType FromTy = D->getType();
35783588
const auto *FromFPT = FromTy->getAs<FunctionProtoType>();

clang/unittests/AST/ASTImporterTest.cpp

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6790,10 +6790,13 @@ TEST_P(ASTImporterOptionSpecificTestBase,
67906790
}
67916791

67926792
struct ImportAutoFunctions : ASTImporterOptionSpecificTestBase {
6793-
void testImport(llvm::StringRef Code, clang::TestLanguage Lang = Lang_CXX14) {
6793+
void testImport(llvm::StringRef Code, clang::TestLanguage Lang = Lang_CXX14,
6794+
bool FindLast = false) {
67946795
Decl *FromTU = getTuDecl(Code, Lang, "input0.cc");
6795-
FunctionDecl *From = FirstDeclMatcher<FunctionDecl>().match(
6796-
FromTU, functionDecl(hasName("foo")));
6796+
FunctionDecl *From = FindLast ? LastDeclMatcher<FunctionDecl>().match(
6797+
FromTU, functionDecl(hasName("foo")))
6798+
: FirstDeclMatcher<FunctionDecl>().match(
6799+
FromTU, functionDecl(hasName("foo")));
67976800

67986801
FunctionDecl *To = Import(From, Lang);
67996802
EXPECT_TRUE(To);
@@ -7232,6 +7235,20 @@ TEST_P(ImportAutoFunctions, ReturnWithTypeInSwitch) {
72327235
Lang_CXX17);
72337236
}
72347237

7238+
TEST_P(ImportAutoFunctions, ReturnWithAutoTemplateType) {
7239+
testImport(
7240+
R"(
7241+
template<class T>
7242+
struct S {};
7243+
template<class T>
7244+
auto foo() {
7245+
return S<T>{};
7246+
}
7247+
auto a = foo<int>();
7248+
)",
7249+
Lang_CXX14, /*FindLast=*/true);
7250+
}
7251+
72357252
struct ImportSourceLocations : ASTImporterOptionSpecificTestBase {};
72367253

72377254
TEST_P(ImportSourceLocations, PreserveFileIDTreeStructure) {

0 commit comments

Comments
 (0)