Skip to content
This repository was archived by the owner on Dec 14, 2021. It is now read-only.

Commit 28b67bc

Browse files
authored
logic: record calls to cxx destructor on delete keyword (issue #829) (#863)
1 parent 270c869 commit 28b67bc

File tree

6 files changed

+74
-5
lines changed

6 files changed

+74
-5
lines changed

src/lib_cxx/data/parser/cxx/CxxAstVisitor.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -583,6 +583,7 @@ DEF_VISIT_TYPE_PTR(DeclRefExpr)
583583
DEF_VISIT_TYPE_PTR(MemberExpr)
584584
DEF_VISIT_TYPE_PTR(CXXDependentScopeMemberExpr)
585585
DEF_VISIT_TYPE_PTR(CXXConstructExpr)
586+
DEF_VISIT_TYPE_PTR(CXXDeleteExpr)
586587
DEF_VISIT_TYPE_PTR(LambdaExpr)
587588
DEF_VISIT_TYPE_PTR(MSAsmStmt)
588589
DEF_VISIT_CUSTOM_TYPE_PTR(ConstructorInitializer, CXXCtorInitializer)

src/lib_cxx/data/parser/cxx/CxxAstVisitor.h

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -98,12 +98,19 @@ class CxxAstVisitor: public clang::RecursiveASTVisitor<CxxAstVisitor>
9898
return TraverseAssignCommon(s); \
9999
}
100100
OPERATOR(Mul)
101-
OPERATOR(Div) OPERATOR(Rem) OPERATOR(Add) OPERATOR(Sub) OPERATOR(Shl) OPERATOR(Shr)
102-
OPERATOR(And) OPERATOR(Or) OPERATOR(Xor)
101+
OPERATOR(Div)
102+
OPERATOR(Rem)
103+
OPERATOR(Add)
104+
OPERATOR(Sub)
105+
OPERATOR(Shl)
106+
OPERATOR(Shr)
107+
OPERATOR(And)
108+
OPERATOR(Or)
109+
OPERATOR(Xor)
103110
#undef OPERATOR
104111

105112

106-
void traverseDeclContextHelper(clang::DeclContext* d);
113+
void traverseDeclContextHelper(clang::DeclContext* d);
107114
bool TraverseCallCommon(clang::CallExpr* s);
108115
bool TraverseAssignCommon(clang::BinaryOperator* s);
109116

@@ -142,6 +149,7 @@ class CxxAstVisitor: public clang::RecursiveASTVisitor<CxxAstVisitor>
142149
virtual bool VisitMemberExpr(clang::MemberExpr* s);
143150
virtual bool VisitCXXDependentScopeMemberExpr(clang::CXXDependentScopeMemberExpr* s);
144151
virtual bool VisitCXXConstructExpr(clang::CXXConstructExpr* s);
152+
virtual bool VisitCXXDeleteExpr(clang::CXXDeleteExpr* s);
145153
virtual bool VisitLambdaExpr(clang::LambdaExpr* s);
146154
virtual bool VisitMSAsmStmt(clang::MSAsmStmt* s);
147155
virtual bool VisitConstructorInitializer(clang::CXXCtorInitializer* init);

src/lib_cxx/data/parser/cxx/CxxAstVisitorComponent.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ class CxxAstVisitorComponent
123123
void visitMemberExpr(clang::MemberExpr* s) {}
124124
void visitCXXDependentScopeMemberExpr(clang::CXXDependentScopeMemberExpr* s) {}
125125
void visitCXXConstructExpr(clang::CXXConstructExpr* s) {}
126+
void visitCXXDeleteExpr(clang::CXXDeleteExpr* s) {}
126127
void visitLambdaExpr(clang::LambdaExpr* s) {}
127128
void visitMSAsmStmt(clang::MSAsmStmt* s) {}
128129

src/lib_cxx/data/parser/cxx/CxxAstVisitorComponentIndexer.cpp

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -783,7 +783,7 @@ void CxxAstVisitorComponentIndexer::visitCXXConstructExpr(clang::CXXConstructExp
783783
loc = clang::Lexer::GetBeginningOfToken(
784784
loc, m_astContext->getSourceManager(), m_astContext->getLangOpts());
785785

786-
Id symbolId = getOrCreateSymbolId(s->getConstructor());
786+
const Id symbolId = getOrCreateSymbolId(s->getConstructor());
787787

788788
const ReferenceKind refKind = consumeDeclRefContextKind();
789789
if (refKind == REFERENCE_CALL)
@@ -800,6 +800,27 @@ void CxxAstVisitorComponentIndexer::visitCXXConstructExpr(clang::CXXConstructExp
800800
}
801801
}
802802

803+
void CxxAstVisitorComponentIndexer::visitCXXDeleteExpr(clang::CXXDeleteExpr* s)
804+
{
805+
if (!s->isArrayForm() && getAstVisitor()->shouldVisitReference(s->getBeginLoc()))
806+
{
807+
if (clang::CXXRecordDecl* recordDecl = s->getDestroyedType()->getAsCXXRecordDecl())
808+
{
809+
if (clang::CXXDestructorDecl* destructorDecl = recordDecl->getDestructor())
810+
{
811+
const Id symbolId = getOrCreateSymbolId(destructorDecl);
812+
813+
m_client->recordReference(
814+
REFERENCE_CALL,
815+
symbolId,
816+
getOrCreateSymbolId(
817+
getAstVisitor()->getComponent<CxxAstVisitorComponentContext>()->getContext()),
818+
getParseLocation(s->getBeginLoc()));
819+
}
820+
}
821+
}
822+
}
823+
803824
void CxxAstVisitorComponentIndexer::visitLambdaExpr(clang::LambdaExpr* s)
804825
{
805826
clang::CXXMethodDecl* methodDecl = s->getCallOperator();

src/lib_cxx/data/parser/cxx/CxxAstVisitorComponentIndexer.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ class CxxAstVisitorComponentIndexer: public CxxAstVisitorComponent
4747
void visitDeclRefExpr(clang::DeclRefExpr* s);
4848
void visitMemberExpr(clang::MemberExpr* s);
4949
void visitCXXConstructExpr(clang::CXXConstructExpr* s);
50+
void visitCXXDeleteExpr(clang::CXXDeleteExpr* s);
5051
void visitLambdaExpr(clang::LambdaExpr* s);
5152

5253
void visitConstructorInitializer(clang::CXXCtorInitializer* init);

src/test/CxxParserTestSuite.cpp

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -845,7 +845,7 @@ TEST_CASE("cxx parser finds template argument of dependent non type template par
845845

846846
// TS_ASSERT(utility::containsElement<std::wstring>(
847847
// client->typeUses, // TODO: record edge between vector<int, Alloc<int>> and Alloc<int> (this
848-
//is an issue because we dont have any typeloc for this edge -.-
848+
// is an issue because we dont have any typeloc for this edge -.-
849849
// ));
850850
//}
851851

@@ -2013,6 +2013,43 @@ TEST_CASE("cxx parser finds explicit constructor call")
20132013
client->calls, L"int main() -> void App::App() <8:2 8:4>"));
20142014
}
20152015

2016+
TEST_CASE("cxx parser finds call of explicitly defined destructor at delete keyword")
2017+
{
2018+
std::shared_ptr<TestIntermediateStorage> client = parseCode(
2019+
"class Foo\n"
2020+
"{\n"
2021+
"public:\n"
2022+
" Foo() {}\n"
2023+
" ~Foo() {}\n"
2024+
"}; \n"
2025+
"\n"
2026+
"void foo()\n"
2027+
"{\n"
2028+
" Foo* f = new Foo(); \n"
2029+
" delete f; \n"
2030+
"}\n");
2031+
2032+
REQUIRE(utility::containsElement<std::wstring>(
2033+
client->calls, L"void foo() -> void Foo::~Foo() <11:2 11:7>"));
2034+
}
2035+
2036+
TEST_CASE("cxx parser finds call of implicitly defined destructor at delete keyword")
2037+
{
2038+
std::shared_ptr<TestIntermediateStorage> client = parseCode(
2039+
"class Foo\n"
2040+
"{\n"
2041+
"}; \n"
2042+
"\n"
2043+
"void foo()\n"
2044+
"{\n"
2045+
" Foo* f = new Foo(); \n"
2046+
" delete f; \n"
2047+
"}\n");
2048+
2049+
REQUIRE(utility::containsElement<std::wstring>(
2050+
client->calls, L"void foo() -> void Foo::~Foo() <8:2 8:7>"));
2051+
}
2052+
20162053
TEST_CASE("cxx parser finds explicit constructor call of field")
20172054
{
20182055
std::shared_ptr<TestIntermediateStorage> client = parseCode(

0 commit comments

Comments
 (0)