Better for-loop/fallthrough branch detection.

This commit is contained in:
Erki 2021-03-04 02:36:12 +02:00
parent a0b9775f13
commit 0509d250ab
4 changed files with 21 additions and 0 deletions

View File

@ -30,6 +30,7 @@ void OperationFinder::processArithmetic(const clang::BinaryOperator* op, const c
log.line = line_number; log.line = line_number;
log.operation = getOpcode(op).str(); log.operation = getOpcode(op).str();
log.current_for_loops = _for_loop_stack; log.current_for_loops = _for_loop_stack;
log.is_fallthrough = _in_fallthrough;
_processExpressionTypes(log, op, op->getLHS(), op->getRHS()); _processExpressionTypes(log, op, op->getLHS(), op->getRHS());
@ -56,6 +57,7 @@ void OperationFinder::processUnaryArithmetic(const clang::UnaryOperator* op, con
log.line = line_number; log.line = line_number;
log.operation = getOpcode(op).str(); log.operation = getOpcode(op).str();
log.current_for_loops = _for_loop_stack; log.current_for_loops = _for_loop_stack;
log.is_fallthrough = _in_fallthrough;
_processExpressionTypes(log, op, lhs, nullptr); _processExpressionTypes(log, op, lhs, nullptr);
@ -64,6 +66,16 @@ void OperationFinder::processUnaryArithmetic(const clang::UnaryOperator* op, con
llvm::outs() << "\n"; llvm::outs() << "\n";
} }
void OperationFinder::fallthroughBranchEntered()
{
_in_fallthrough = true;
}
void OperationFinder::fallthroughBranchExited()
{
_in_fallthrough = false;
}
void OperationFinder::forLoopEntered() void OperationFinder::forLoopEntered()
{ {
_for_loop_stack.push_back(_next_for_loop_id); _for_loop_stack.push_back(_next_for_loop_id);

View File

@ -17,6 +17,9 @@ public:
void processArithmetic(const clang::BinaryOperator* op, const clang::SourceManager& source_manager); void processArithmetic(const clang::BinaryOperator* op, const clang::SourceManager& source_manager);
void processUnaryArithmetic(const clang::UnaryOperator* op, const clang::SourceManager& source_manager); void processUnaryArithmetic(const clang::UnaryOperator* op, const clang::SourceManager& source_manager);
void fallthroughBranchEntered();
void fallthroughBranchExited();
void forLoopEntered(); void forLoopEntered();
void forLoopExited(); void forLoopExited();
@ -24,6 +27,7 @@ private:
void _processExpressionTypes(OperationLog& log, const clang::Expr* source, const clang::Expr* op1, const clang::Expr* op2); void _processExpressionTypes(OperationLog& log, const clang::Expr* source, const clang::Expr* op1, const clang::Expr* op2);
int _next_for_loop_id = 0; int _next_for_loop_id = 0;
bool _in_fallthrough = false;
std::vector<int> _for_loop_stack; std::vector<int> _for_loop_stack;
IOperationOutput* _storage; IOperationOutput* _storage;
}; };

View File

@ -52,6 +52,7 @@ bool OperationFinderAstVisitor::dataTraverseStmtPre(clang::Stmt* stmt)
if (loop->getInit()) if (loop->getInit())
{ {
_loop_init = loop->getInit(); _loop_init = loop->getInit();
_op_finder->fallthroughBranchEntered();
} }
else else
{ {
@ -69,6 +70,7 @@ bool OperationFinderAstVisitor::dataTraverseStmtPost(clang::Stmt* stmt)
if (_loop_init && _loop_init == stmt) if (_loop_init && _loop_init == stmt)
{ {
_op_finder->forLoopEntered(); _op_finder->forLoopEntered();
_op_finder->fallthroughBranchExited();
_loop_init = nullptr; _loop_init = nullptr;
} }
else if (clang::dyn_cast<clang::ForStmt>(stmt)) else if (clang::dyn_cast<clang::ForStmt>(stmt))

View File

@ -14,6 +14,7 @@ struct OperationLog
std::string operand_lhs; std::string operand_lhs;
std::string operand_rhs; std::string operand_rhs;
std::string operand_result; std::string operand_result;
bool is_fallthrough;
std::vector<int> current_for_loops; std::vector<int> current_for_loops;
}; };
@ -35,6 +36,7 @@ inline void to_json(nlohmann::json& j, const OperationLog& l)
{"operand_lhs", l.operand_lhs}, {"operand_lhs", l.operand_lhs},
{"operand_rhs", l.operand_rhs}, {"operand_rhs", l.operand_rhs},
{"operand_result", l.operand_result}, {"operand_result", l.operand_result},
{"is_fallthrough", l.is_fallthrough},
{"current_for_loops", l.current_for_loops} {"current_for_loops", l.current_for_loops}
}; };
} }
@ -46,6 +48,7 @@ inline void from_json(const nlohmann::json& j, OperationLog& l)
j.at("operand_lhs").get_to(l.operand_lhs); j.at("operand_lhs").get_to(l.operand_lhs);
j.at("operand_rhs").get_to(l.operand_rhs); j.at("operand_rhs").get_to(l.operand_rhs);
j.at("operand_result").get_to(l.operand_result); j.at("operand_result").get_to(l.operand_result);
j.at("is_fallthrough").get_to(l.is_fallthrough);
j.at("current_for_loops").get_to(l.current_for_loops); j.at("current_for_loops").get_to(l.current_for_loops);
} }