logic: record calls to cxx destructor on delete keyword (issue #829) (#863)

This commit is contained in:
Malte Langkabel
2019-12-29 23:05:24 +01:00
committed by GitHub
parent 270c8698dc
commit 28b67bc91d
6 changed files with 74 additions and 5 deletions
@@ -583,6 +583,7 @@ DEF_VISIT_TYPE_PTR(DeclRefExpr)
DEF_VISIT_TYPE_PTR(MemberExpr)
DEF_VISIT_TYPE_PTR(CXXDependentScopeMemberExpr)
DEF_VISIT_TYPE_PTR(CXXConstructExpr)
DEF_VISIT_TYPE_PTR(CXXDeleteExpr)
DEF_VISIT_TYPE_PTR(LambdaExpr)
DEF_VISIT_TYPE_PTR(MSAsmStmt)
DEF_VISIT_CUSTOM_TYPE_PTR(ConstructorInitializer, CXXCtorInitializer)
+11 -3
View File
@@ -98,12 +98,19 @@ public:
return TraverseAssignCommon(s); \
}
OPERATOR(Mul)
OPERATOR(Div) OPERATOR(Rem) OPERATOR(Add) OPERATOR(Sub) OPERATOR(Shl) OPERATOR(Shr)
OPERATOR(And) OPERATOR(Or) OPERATOR(Xor)
OPERATOR(Div)
OPERATOR(Rem)
OPERATOR(Add)
OPERATOR(Sub)
OPERATOR(Shl)
OPERATOR(Shr)
OPERATOR(And)
OPERATOR(Or)
OPERATOR(Xor)
#undef OPERATOR
void traverseDeclContextHelper(clang::DeclContext* d);
void traverseDeclContextHelper(clang::DeclContext* d);
bool TraverseCallCommon(clang::CallExpr* s);
bool TraverseAssignCommon(clang::BinaryOperator* s);
@@ -142,6 +149,7 @@ public:
virtual bool VisitMemberExpr(clang::MemberExpr* s);
virtual bool VisitCXXDependentScopeMemberExpr(clang::CXXDependentScopeMemberExpr* s);
virtual bool VisitCXXConstructExpr(clang::CXXConstructExpr* s);
virtual bool VisitCXXDeleteExpr(clang::CXXDeleteExpr* s);
virtual bool VisitLambdaExpr(clang::LambdaExpr* s);
virtual bool VisitMSAsmStmt(clang::MSAsmStmt* s);
virtual bool VisitConstructorInitializer(clang::CXXCtorInitializer* init);
@@ -123,6 +123,7 @@ public:
void visitMemberExpr(clang::MemberExpr* s) {}
void visitCXXDependentScopeMemberExpr(clang::CXXDependentScopeMemberExpr* s) {}
void visitCXXConstructExpr(clang::CXXConstructExpr* s) {}
void visitCXXDeleteExpr(clang::CXXDeleteExpr* s) {}
void visitLambdaExpr(clang::LambdaExpr* s) {}
void visitMSAsmStmt(clang::MSAsmStmt* s) {}
@@ -783,7 +783,7 @@ void CxxAstVisitorComponentIndexer::visitCXXConstructExpr(clang::CXXConstructExp
loc = clang::Lexer::GetBeginningOfToken(
loc, m_astContext->getSourceManager(), m_astContext->getLangOpts());
Id symbolId = getOrCreateSymbolId(s->getConstructor());
const Id symbolId = getOrCreateSymbolId(s->getConstructor());
const ReferenceKind refKind = consumeDeclRefContextKind();
if (refKind == REFERENCE_CALL)
@@ -800,6 +800,27 @@ void CxxAstVisitorComponentIndexer::visitCXXConstructExpr(clang::CXXConstructExp
}
}
void CxxAstVisitorComponentIndexer::visitCXXDeleteExpr(clang::CXXDeleteExpr* s)
{
if (!s->isArrayForm() && getAstVisitor()->shouldVisitReference(s->getBeginLoc()))
{
if (clang::CXXRecordDecl* recordDecl = s->getDestroyedType()->getAsCXXRecordDecl())
{
if (clang::CXXDestructorDecl* destructorDecl = recordDecl->getDestructor())
{
const Id symbolId = getOrCreateSymbolId(destructorDecl);
m_client->recordReference(
REFERENCE_CALL,
symbolId,
getOrCreateSymbolId(
getAstVisitor()->getComponent<CxxAstVisitorComponentContext>()->getContext()),
getParseLocation(s->getBeginLoc()));
}
}
}
}
void CxxAstVisitorComponentIndexer::visitLambdaExpr(clang::LambdaExpr* s)
{
clang::CXXMethodDecl* methodDecl = s->getCallOperator();
@@ -47,6 +47,7 @@ public:
void visitDeclRefExpr(clang::DeclRefExpr* s);
void visitMemberExpr(clang::MemberExpr* s);
void visitCXXConstructExpr(clang::CXXConstructExpr* s);
void visitCXXDeleteExpr(clang::CXXDeleteExpr* s);
void visitLambdaExpr(clang::LambdaExpr* s);
void visitConstructorInitializer(clang::CXXCtorInitializer* init);
+38 -1
View File
@@ -845,7 +845,7 @@ TEST_CASE("cxx parser finds template argument of dependent non type template par
// TS_ASSERT(utility::containsElement<std::wstring>(
// client->typeUses, // TODO: record edge between vector<int, Alloc<int>> and Alloc<int> (this
//is an issue because we dont have any typeloc for this edge -.-
// is an issue because we dont have any typeloc for this edge -.-
// ));
//}
@@ -2013,6 +2013,43 @@ TEST_CASE("cxx parser finds explicit constructor call")
client->calls, L"int main() -> void App::App() <8:2 8:4>"));
}
TEST_CASE("cxx parser finds call of explicitly defined destructor at delete keyword")
{
std::shared_ptr<TestIntermediateStorage> client = parseCode(
"class Foo\n"
"{\n"
"public:\n"
" Foo() {}\n"
" ~Foo() {}\n"
"}; \n"
"\n"
"void foo()\n"
"{\n"
" Foo* f = new Foo(); \n"
" delete f; \n"
"}\n");
REQUIRE(utility::containsElement<std::wstring>(
client->calls, L"void foo() -> void Foo::~Foo() <11:2 11:7>"));
}
TEST_CASE("cxx parser finds call of implicitly defined destructor at delete keyword")
{
std::shared_ptr<TestIntermediateStorage> client = parseCode(
"class Foo\n"
"{\n"
"}; \n"
"\n"
"void foo()\n"
"{\n"
" Foo* f = new Foo(); \n"
" delete f; \n"
"}\n");
REQUIRE(utility::containsElement<std::wstring>(
client->calls, L"void foo() -> void Foo::~Foo() <8:2 8:7>"));
}
TEST_CASE("cxx parser finds explicit constructor call of field")
{
std::shared_ptr<TestIntermediateStorage> client = parseCode(