Skip to content

Commit

Permalink
#12: match empty serializers
Browse files Browse the repository at this point in the history
  • Loading branch information
cz4rs committed Feb 10, 2021
1 parent cd22c64 commit f776415
Showing 1 changed file with 39 additions and 25 deletions.
64 changes: 39 additions & 25 deletions src/plugin/plugin.cc
Original file line number Diff line number Diff line change
Expand Up @@ -64,25 +64,32 @@ void printWarning(FieldDecl const* field_decl) {
llvm::errs() << " is not serialized.\n";
}

void SanitizerMatcher::run(MatchFinder::MatchResult const& result) {
auto record = result.Nodes.getNodeAs<CXXRecordDecl>("record");
// auto method = result.Nodes.getNodeAs<FunctionTemplateDecl>("method");
std::unordered_set<FieldDecl const*>getSerializedFields(
MatchFinder::MatchResult const& result
) {
std::unordered_set<FieldDecl const*> serialized;
auto binary_op = result.Nodes.getNodeAs<BinaryOperator>("binary");
if (binary_op != nullptr) {
Expr const* lhs;
do {
lhs = binary_op->getLHS();
auto rhs_member_expr = dyn_cast<MemberExpr>(binary_op->getRHS());
if (!rhs_member_expr) {
continue; // possibly CXXDependentScopeMemberExpr
}
auto field = dyn_cast<FieldDecl>(rhs_member_expr->getMemberDecl());
serialized.insert(field->getFirstDecl());
} while ((binary_op = dyn_cast<BinaryOperator>(lhs)));
}

// llvm::errs() << "\nProcessing serialized fields [" << record->getQualifiedNameAsString() << "]\n";
std::unordered_set<FieldDecl const*> serialized;
Expr const* lhs;
do {
lhs = binary_op->getLHS();
auto rhs_member_expr = dyn_cast<MemberExpr>(binary_op->getRHS());
if (!rhs_member_expr) {
continue; // possibly CXXDependentScopeMemberExpr
}
auto field = dyn_cast<FieldDecl>(rhs_member_expr->getMemberDecl());
serialized.insert(field->getFirstDecl());
} while ((binary_op = dyn_cast<BinaryOperator>(lhs)));
return serialized;
}

void SanitizerMatcher::run(MatchFinder::MatchResult const& result) {
auto record = result.Nodes.getNodeAs<CXXRecordDecl>("record");
// llvm::errs() << "Processing " << record->getQualifiedNameAsString() << "\n";

// llvm::errs() << "Processing fields [" << record->getQualifiedNameAsString() << "]\n";
auto serialized = getSerializedFields(result);
for (auto field : record->fields()) {
if (serialized.find(field->getFirstDecl()) == serialized.end()) {
printWarning(field);
Expand All @@ -91,21 +98,28 @@ void SanitizerMatcher::run(MatchFinder::MatchResult const& result) {
}

SanitizerASTConsumer::SanitizerASTConsumer() {
auto serialize_matcher =
auto binary_op =
cxxRecordDecl(
has(functionTemplateDecl(
hasName("serialize"), has(cxxMethodDecl(
parameterCountIs(1),
hasDescendant(binaryOperator().bind("binary"))
))
))
).bind("record");

auto empty_body =
cxxRecordDecl(
has(functionTemplateDecl(
hasName("serialize"), has(cxxMethodDecl(
parameterCountIs(1), has(compoundStmt(
has(binaryOperator().bind("binary"))
// TODO: consider empty serialize.
// Note: "Adding more than one 'NodeMatch' allows finding different
// matches in a single pass over the AST."
))
parameterCountIs(1),
has(compoundStmt(statementCountIs(0)))
))
).bind("method"))
))
).bind("record");

finder_.addMatcher(serialize_matcher, &callback_);
finder_.addMatcher(binary_op, &callback_);
finder_.addMatcher(empty_body, &callback_);
}


Expand Down

0 comments on commit f776415

Please sign in to comment.