From 22627d7a1f5f4a719beb640a3615e2f9e86b9e3e Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Fri, 3 Aug 2018 16:11:32 -0700 Subject: [PATCH] Validate RecordDecl --- .../usage/func_called_from_template.cc | 2 +- src/indexer.cc | 25 ++++++++++++++++--- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/index_tests/usage/func_called_from_template.cc b/index_tests/usage/func_called_from_template.cc index 868cc1b0..becca51b 100644 --- a/index_tests/usage/func_called_from_template.cc +++ b/index_tests/usage/func_called_from_template.cc @@ -27,7 +27,7 @@ OUTPUT: "bases": [], "derived": [], "vars": [], - "uses": ["5:3-5:9|10177235824697315808|3|16420", "5:3-5:9|2459767597003442547|3|16420"], + "uses": ["5:3-5:9|10177235824697315808|3|16420"], "callees": [] }, { "usr": 2459767597003442547, diff --git a/src/indexer.cc b/src/indexer.cc index 3217bb18..2ff9f9fb 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -301,6 +301,19 @@ const Decl* GetSpecialized(const Decl* D) { return Template; } +bool ValidateRecord(const RecordDecl *RD) { + for (const auto *I : RD->fields()){ + QualType FQT = I->getType(); + if (FQT->isIncompleteType() || FQT->isDependentType()) + return false; + if (const RecordType *ChildType = I->getType()->getAs()) + if (const RecordDecl *Child = ChildType->getDecl()) + if (!ValidateRecord(Child)) + return false; + } + return true; +} + class IndexDataConsumer : public index::IndexDataConsumer { public: ASTContext *Ctx; @@ -828,18 +841,24 @@ public: : lsSymbolKind::Class; if (is_def) { SmallVector, 2> Stack{{RD, 0}}; + llvm::DenseSet Seen; + Seen.insert(RD); while (Stack.size()) { int offset; std::tie(RD, offset) = Stack.back(); Stack.pop_back(); - if (!RD->isCompleteDefinition() || RD->isDependentType()) + if (!RD->isCompleteDefinition() || RD->isDependentType() || + !ValidateRecord(RD)) offset = -1; for (FieldDecl *FD : RD->fields()) { int offset1 = offset >= 0 ? offset + Ctx->getFieldOffset(FD) : -1; if (FD->getIdentifier()) type->def.vars.emplace_back(GetUsr(FD), offset1); - else if (const auto *RT1 = FD->getType()->getAs()) - Stack.push_back({RT1->getDecl(), offset1}); + else if (const auto *RT1 = FD->getType()->getAs()) { + if (const RecordDecl *RD1 = RT1->getDecl()) + if (Seen.insert(RD1).second) + Stack.push_back({RD1, offset1}); + } } } }