//===- ExprEngineVisitTest.cpp --------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #include "CheckerRegistration.h" #include "clang/AST/Stmt.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" #include "clang/StaticAnalyzer/Core/Checker.h" #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" #include "gtest/gtest.h" using namespace clang; using namespace ento; namespace { void emitErrorReport(CheckerContext &C, const BugType &Bug, const std::string &Desc) { if (ExplodedNode *Node = C.generateNonFatalErrorNode(C.getState())) { auto Report = std::make_unique(Bug, Desc, Node); C.emitReport(std::move(Report)); } } #define CREATE_EXPR_ENGINE_CHECKER(CHECKER_NAME, CALLBACK, STMT_TYPE, \ BUG_NAME) \ class CHECKER_NAME : public Checker> { \ public: \ void check##CALLBACK(const STMT_TYPE *ASM, CheckerContext &C) const { \ emitErrorReport(C, Bug, "check" #CALLBACK "<" #STMT_TYPE ">"); \ } \ \ private: \ const BugType Bug{this, BUG_NAME}; \ }; CREATE_EXPR_ENGINE_CHECKER(ExprEngineVisitPreChecker, PreStmt, GCCAsmStmt, "GCCAsmStmtBug") CREATE_EXPR_ENGINE_CHECKER(ExprEngineVisitPostChecker, PostStmt, GCCAsmStmt, "GCCAsmStmtBug") void addExprEngineVisitPreChecker(AnalysisASTConsumer &AnalysisConsumer, AnalyzerOptions &AnOpts) { AnOpts.CheckersAndPackages = {{"ExprEngineVisitPreChecker", true}}; AnalysisConsumer.AddCheckerRegistrationFn([](CheckerRegistry &Registry) { Registry.addChecker("ExprEngineVisitPreChecker", "Desc", "DocsURI"); }); } void addExprEngineVisitPostChecker(AnalysisASTConsumer &AnalysisConsumer, AnalyzerOptions &AnOpts) { AnOpts.CheckersAndPackages = {{"ExprEngineVisitPostChecker", true}}; AnalysisConsumer.AddCheckerRegistrationFn([](CheckerRegistry &Registry) { Registry.addChecker( "ExprEngineVisitPostChecker", "Desc", "DocsURI"); }); } TEST(ExprEngineVisitTest, checkPreStmtGCCAsmStmt) { std::string Diags; EXPECT_TRUE(runCheckerOnCode(R"( void top() { asm(""); } )", Diags)); EXPECT_EQ(Diags, "ExprEngineVisitPreChecker: checkPreStmt\n"); } TEST(ExprEngineVisitTest, checkPostStmtGCCAsmStmt) { std::string Diags; EXPECT_TRUE(runCheckerOnCode(R"( void top() { asm(""); } )", Diags)); EXPECT_EQ(Diags, "ExprEngineVisitPostChecker: checkPostStmt\n"); } } // namespace