Skip to content

Commit

Permalink
[clang][ASTImporter] skip TemplateTypeParmDecl in VisitTypeAliasTempl…
Browse files Browse the repository at this point in the history
…ateDecl (#74919)

Skip checking `TemplateTypeParmDecl ` in `VisitTypeAliasTemplateDecl`.
[Fix this crash](#74765)

Co-authored-by: huqizhi <836744285@qq.com>
  • Loading branch information
jcsxky committed Dec 25, 2023
1 parent 34727b0 commit 9b99a30
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 4 deletions.
9 changes: 5 additions & 4 deletions clang/lib/AST/ASTImporter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2771,9 +2771,11 @@ ASTNodeImporter::VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D) {
for (auto *FoundDecl : FoundDecls) {
if (!FoundDecl->isInIdentifierNamespace(IDNS))
continue;
if (auto *FoundAlias = dyn_cast<TypeAliasTemplateDecl>(FoundDecl))
return Importer.MapImported(D, FoundAlias);
ConflictingDecls.push_back(FoundDecl);
if (auto *FoundAlias = dyn_cast<TypeAliasTemplateDecl>(FoundDecl)) {
if (IsStructuralMatch(D, FoundAlias))
return Importer.MapImported(D, FoundAlias);
ConflictingDecls.push_back(FoundDecl);
}
}

if (!ConflictingDecls.empty()) {
Expand Down Expand Up @@ -9402,7 +9404,6 @@ Expected<Decl *> ASTImporter::Import(Decl *FromD) {
setImportDeclError(FromD, *Error);
return make_error<ASTImportError>(*Error);
}

// Make sure that ImportImpl registered the imported decl.
assert(ImportedDecls.count(FromD) != 0 && "Missing call to MapImported?");
if (auto Error = ImportAttrs(ToD, FromD))
Expand Down
12 changes: 12 additions & 0 deletions clang/lib/AST/ASTStructuralEquivalence.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1977,6 +1977,18 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
D2->getTemplatedDecl()->getType());
}

static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
TypeAliasTemplateDecl *D1,
TypeAliasTemplateDecl *D2) {
// Check template parameters.
if (!IsTemplateDeclCommonStructurallyEquivalent(Context, D1, D2))
return false;

// Check the templated declaration.
return IsStructurallyEquivalent(Context, D1->getTemplatedDecl(),
D2->getTemplatedDecl());
}

static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
ConceptDecl *D1,
ConceptDecl *D2) {
Expand Down
47 changes: 47 additions & 0 deletions clang/unittests/AST/ASTImporterTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9295,6 +9295,53 @@ TEST_P(ASTImporterOptionSpecificTestBase,
// EXPECT_EQ(ToF1Imported->getPreviousDecl(), ToF1);
}

TEST_P(ASTImporterOptionSpecificTestBase,
ImportTypeAliasTemplateAfterSimilarCalledTemplateTypeParm) {
const char *Code =
R"(
struct S;
template <typename>
using Callable = S;
template <typename Callable>
int bindingFunctionVTable;
)";
Decl *FromTU = getTuDecl(Code, Lang_CXX17);

auto *FromCallable = FirstDeclMatcher<TypeAliasTemplateDecl>().match(
FromTU, typeAliasTemplateDecl(hasName("Callable")));

auto *FromCallableParm = FirstDeclMatcher<TemplateTypeParmDecl>().match(
FromTU, templateTypeParmDecl(hasName("Callable")));

auto *ToFromCallableParm = Import(FromCallableParm, Lang_CXX17);
auto *ToCallable = Import(FromCallable, Lang_CXX17);
EXPECT_TRUE(ToFromCallableParm);
EXPECT_TRUE(ToCallable);
}

TEST_P(ASTImporterOptionSpecificTestBase, ImportConflictTypeAliasTemplate) {
const char *ToCode =
R"(
struct S;
template <typename, typename>
using Callable = S;
)";
const char *Code =
R"(
struct S;
template <typename>
using Callable = S;
)";
(void)getToTuDecl(ToCode, Lang_CXX17);
Decl *FromTU = getTuDecl(Code, Lang_CXX17);

auto *FromCallable = FirstDeclMatcher<TypeAliasTemplateDecl>().match(
FromTU, typeAliasTemplateDecl(hasName("Callable")));

auto *ImportedCallable = Import(FromCallable, Lang_CXX17);
EXPECT_FALSE(ImportedCallable);
}

INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ASTImporterLookupTableTest,
DefaultTestValuesForRunOptions);

Expand Down

0 comments on commit 9b99a30

Please sign in to comment.