r335740 - [analyzer] Allow registering custom statically-linked analyzer checkers

Artem Belevich via cfe-commits cfe-commits at lists.llvm.org
Wed Jun 27 14:30:08 PDT 2018


FYI,

This commit breaks clang tests. It appears that StaticAnalysisTests misses
dependency on clangFrontend.

--Artem

[60/134] Linking CXX executable
tools/clang/unittests/StaticAnalyzer/StaticAnalysisTests
FAILED: tools/clang/unittests/StaticAnalyzer/StaticAnalysisTests
: && /usr/local/google/home/tra/local/clang/bin/clang++   -fPIC
-fvisibility-inlines-hidden -Werror=date-time
-Werror=unguarded-availability-new -std=c++11 -Wall -Wextra
-Wno-unused-parameter -Wwrite-strings -Wcast-qual
-Wmissing-field-initializers -pedantic -Wno-long-long
-Wcovered-switch-default -Wnon-virtual-dtor -Wdelete-non-virtual-dtor
-Wstring-conversion -fdiagnostics-color -fno-common -Woverloaded-virtual
-Wno-nested-anon-types -g  -fuse-ld=lld -Xlinker --gdb-index -fuse-ld=lld
-Wl,--color-diagnostics -Wl,-allow-shlib-undefined
tools/clang/unittests/StaticAnalyzer/CMakeFiles/StaticAnalysisTests.dir/AnalyzerOptionsTest.cpp.o
tools/clang/unittests/StaticAnalyzer/CMakeFiles/StaticAnalysisTests.dir/RegisterCustomCheckersTest.cpp.o
-o tools/clang/unittests/StaticAnalyzer/StaticAnalysisTests
lib/libLLVMSupport.so.7svn -lpthread lib/libgtest_main.so.7svn
lib/libgtest.so.7svn -lpthread lib/libclangBasic.so.7svn
lib/libclangAnalysis.so.7svn lib/libclangStaticAnalyzerCore.so.7svn
lib/libclangStaticAnalyzerFrontend.so.7svn lib/libclangTooling.so.7svn
-Wl,-rpath,/usr/local/google/home/tra/work/llvm/build/release+assert/lib &&
:
/usr/local/google/home/tra/local/clang/bin/ld.lld: error: undefined symbol:
clang::FrontendAction::FrontendAction()
>>> referenced by FrontendAction.h:235
(/usr/local/google/home/tra/work/llvm/repo/clang/include/clang/Frontend/FrontendAction.h:235)
>>>
 tools/clang/unittests/StaticAnalyzer/CMakeFiles/StaticAnalysisTests.dir/RegisterCustomCheckersTest.cpp.o:(clang::ASTFrontendAction::ASTFrontendAction())

/usr/local/google/home/tra/local/clang/bin/ld.lld: error: undefined symbol:
vtable for clang::ASTFrontendAction
>>> referenced by FrontendAction.h:235
(/usr/local/google/home/tra/work/llvm/repo/clang/include/clang/Frontend/FrontendAction.h:235)
>>>
 tools/clang/unittests/StaticAnalyzer/CMakeFiles/StaticAnalysisTests.dir/RegisterCustomCheckersTest.cpp.o:(clang::ASTFrontendAction::ASTFrontendAction())

/usr/local/google/home/tra/local/clang/bin/ld.lld: error: undefined symbol:
clang::FrontendAction::~FrontendAction()
>>> referenced by FrontendAction.h:225
(/usr/local/google/home/tra/work/llvm/repo/clang/include/clang/Frontend/FrontendAction.h:225)
>>>
 tools/clang/unittests/StaticAnalyzer/CMakeFiles/StaticAnalysisTests.dir/RegisterCustomCheckersTest.cpp.o:(clang::ASTFrontendAction::~ASTFrontendAction())

/usr/local/google/home/tra/local/clang/bin/ld.lld: error: undefined symbol:
clang::PCHContainerOperations::PCHContainerOperations()
>>> referenced by new_allocator.h:136
(/usr/lib/gcc/x86_64-linux-gnu/7.3.0/../../../../include/c++/7.3.0/ext/new_allocator.h:136)
>>>
 tools/clang/unittests/StaticAnalyzer/CMakeFiles/StaticAnalysisTests.dir/RegisterCustomCheckersTest.cpp.o:(void
__gnu_cxx::new_allocator<clang::PCHContainerOperations>::construct<clang::PCHContainerOperations>(clang::PCHContainerOperations*))

/usr/local/google/home/tra/local/clang/bin/ld.lld: error: undefined symbol:
clang::ASTFrontendAction::ExecuteAction()
>>> referenced by RegisterCustomCheckersTest.cpp
>>>
 tools/clang/unittests/StaticAnalyzer/CMakeFiles/StaticAnalysisTests.dir/RegisterCustomCheckersTest.cpp.o:(vtable
for clang::ento::(anonymous namespace)::TestAction)

/usr/local/google/home/tra/local/clang/bin/ld.lld: error: undefined symbol:
clang::FrontendAction::shouldEraseOutputFiles()
>>> referenced by RegisterCustomCheckersTest.cpp
>>>
 tools/clang/unittests/StaticAnalyzer/CMakeFiles/StaticAnalysisTests.dir/RegisterCustomCheckersTest.cpp.o:(vtable
for clang::ento::(anonymous namespace)::TestAction)
clang: error: linker command failed with exit code 1 (use -v to see
invocation)


On Wed, Jun 27, 2018 at 8:00 AM Alexander Kornienko via cfe-commits <
cfe-commits at lists.llvm.org> wrote:

> Author: alexfh
> Date: Wed Jun 27 07:56:12 2018
> New Revision: 335740
>
> URL: http://llvm.org/viewvc/llvm-project?rev=335740&view=rev
> Log:
> [analyzer] Allow registering custom statically-linked analyzer checkers
>
> Summary:
> Add an extension point to allow registration of statically-linked Clang
> Static
> Analyzer checkers that are not a part of the Clang tree. This extension
> point
> employs the mechanism used when checkers are registered from dynamically
> loaded
> plugins.
>
> Reviewers: george.karpenkov, NoQ, xazax.hun, dcoughlin
>
> Reviewed By: george.karpenkov
>
> Subscribers: mgorny, mikhail.ramalho, rnkovacs, xazax.hun, szepet,
> a.sidorin, cfe-commits
>
> Differential Revision: https://reviews.llvm.org/D45718
>
> Added:
>     cfe/trunk/unittests/StaticAnalyzer/RegisterCustomCheckersTest.cpp
> Modified:
>     cfe/trunk/include/clang/StaticAnalyzer/Frontend/AnalysisConsumer.h
>     cfe/trunk/include/clang/StaticAnalyzer/Frontend/CheckerRegistration.h
>     cfe/trunk/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
>     cfe/trunk/lib/StaticAnalyzer/Frontend/CheckerRegistration.cpp
>     cfe/trunk/unittests/StaticAnalyzer/AnalyzerOptionsTest.cpp
>     cfe/trunk/unittests/StaticAnalyzer/CMakeLists.txt
>
> Modified:
> cfe/trunk/include/clang/StaticAnalyzer/Frontend/AnalysisConsumer.h
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Frontend/AnalysisConsumer.h?rev=335740&r1=335739&r2=335740&view=diff
>
> ==============================================================================
> --- cfe/trunk/include/clang/StaticAnalyzer/Frontend/AnalysisConsumer.h
> (original)
> +++ cfe/trunk/include/clang/StaticAnalyzer/Frontend/AnalysisConsumer.h Wed
> Jun 27 07:56:12 2018
> @@ -17,6 +17,7 @@
>
>  #include "clang/AST/ASTConsumer.h"
>  #include "clang/Basic/LLVM.h"
> +#include <functional>
>  #include <memory>
>
>  namespace clang {
> @@ -29,10 +30,24 @@ class CompilerInstance;
>  namespace ento {
>  class PathDiagnosticConsumer;
>  class CheckerManager;
> +class CheckerRegistry;
>
>  class AnalysisASTConsumer : public ASTConsumer {
>  public:
>    virtual void AddDiagnosticConsumer(PathDiagnosticConsumer *Consumer) =
> 0;
> +
> +  /// This method allows registering statically linked custom checkers
> that are
> +  /// not a part of the Clang tree. It employs the same mechanism that is
> used
> +  /// by plugins.
> +  ///
> +  /// Example:
> +  ///
> +  ///   Consumer->AddCheckerRegistrationFn([] (CheckerRegistry& Registry)
> {
> +  ///     Registry.addChecker<MyCustomChecker>("example.MyCustomChecker",
> +  ///                                          "Description");
> +  ///   });
> +  virtual void
> +  AddCheckerRegistrationFn(std::function<void(CheckerRegistry &)> Fn) = 0;
>  };
>
>  /// CreateAnalysisConsumer - Creates an ASTConsumer to run various code
>
> Modified:
> cfe/trunk/include/clang/StaticAnalyzer/Frontend/CheckerRegistration.h
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Frontend/CheckerRegistration.h?rev=335740&r1=335739&r2=335740&view=diff
>
> ==============================================================================
> --- cfe/trunk/include/clang/StaticAnalyzer/Frontend/CheckerRegistration.h
> (original)
> +++ cfe/trunk/include/clang/StaticAnalyzer/Frontend/CheckerRegistration.h
> Wed Jun 27 07:56:12 2018
> @@ -11,6 +11,7 @@
>  #define LLVM_CLANG_STATICANALYZER_FRONTEND_CHECKERREGISTRATION_H
>
>  #include "clang/Basic/LLVM.h"
> +#include <functional>
>  #include <memory>
>  #include <string>
>
> @@ -21,10 +22,13 @@ namespace clang {
>
>  namespace ento {
>    class CheckerManager;
> +  class CheckerRegistry;
>
> -  std::unique_ptr<CheckerManager>
> -  createCheckerManager(AnalyzerOptions &opts, const LangOptions &langOpts,
> -                       ArrayRef<std::string> plugins, DiagnosticsEngine
> &diags);
> +  std::unique_ptr<CheckerManager> createCheckerManager(
> +      AnalyzerOptions &opts, const LangOptions &langOpts,
> +      ArrayRef<std::string> plugins,
> +      ArrayRef<std::function<void(CheckerRegistry &)>>
> checkerRegistrationFns,
> +      DiagnosticsEngine &diags);
>
>  } // end ento namespace
>
>
> Modified: cfe/trunk/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp?rev=335740&r1=335739&r2=335740&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp (original)
> +++ cfe/trunk/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp Wed Jun 27
> 07:56:12 2018
> @@ -164,6 +164,8 @@ class AnalysisConsumer : public Analysis
>    /// Bug Reporter to use while recursively visiting Decls.
>    BugReporter *RecVisitorBR;
>
> +  std::vector<std::function<void(CheckerRegistry &)>>
> CheckerRegistrationFns;
> +
>  public:
>    ASTContext *Ctx;
>    const Preprocessor &PP;
> @@ -293,8 +295,9 @@ public:
>
>    void Initialize(ASTContext &Context) override {
>      Ctx = &Context;
> -    checkerMgr = createCheckerManager(*Opts, PP.getLangOpts(), Plugins,
> -                                      PP.getDiagnostics());
> +    checkerMgr =
> +        createCheckerManager(*Opts, PP.getLangOpts(), Plugins,
> +                             CheckerRegistrationFns, PP.getDiagnostics());
>
>      Mgr = llvm::make_unique<AnalysisManager>(
>          *Ctx, PP.getDiagnostics(), PP.getLangOpts(), PathConsumers,
> @@ -385,6 +388,10 @@ public:
>      PathConsumers.push_back(Consumer);
>    }
>
> +  void AddCheckerRegistrationFn(std::function<void(CheckerRegistry&)> Fn)
> override {
> +    CheckerRegistrationFns.push_back(std::move(Fn));
> +  }
> +
>  private:
>    void storeTopLevelDecls(DeclGroupRef DG);
>    std::string getFunctionName(const Decl *D);
>
> Modified: cfe/trunk/lib/StaticAnalyzer/Frontend/CheckerRegistration.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Frontend/CheckerRegistration.cpp?rev=335740&r1=335739&r2=335740&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/StaticAnalyzer/Frontend/CheckerRegistration.cpp
> (original)
> +++ cfe/trunk/lib/StaticAnalyzer/Frontend/CheckerRegistration.cpp Wed Jun
> 27 07:56:12 2018
> @@ -111,16 +111,21 @@ getCheckerOptList(const AnalyzerOptions
>    return checkerOpts;
>  }
>
> -std::unique_ptr<CheckerManager>
> -ento::createCheckerManager(AnalyzerOptions &opts, const LangOptions
> &langOpts,
> -                           ArrayRef<std::string> plugins,
> -                           DiagnosticsEngine &diags) {
> +std::unique_ptr<CheckerManager> ento::createCheckerManager(
> +    AnalyzerOptions &opts, const LangOptions &langOpts,
> +    ArrayRef<std::string> plugins,
> +    ArrayRef<std::function<void(CheckerRegistry &)>>
> checkerRegistrationFns,
> +    DiagnosticsEngine &diags) {
>    std::unique_ptr<CheckerManager> checkerMgr(
>        new CheckerManager(langOpts, opts));
>
>    SmallVector<CheckerOptInfo, 8> checkerOpts = getCheckerOptList(opts);
>
>    ClangCheckerRegistry allCheckers(plugins, &diags);
> +
> +  for (const auto &Fn : checkerRegistrationFns)
> +    Fn(allCheckers);
> +
>    allCheckers.initializeManager(*checkerMgr, checkerOpts);
>    allCheckers.validateCheckerOptions(opts, diags);
>    checkerMgr->finishedCheckerRegistration();
>
> Modified: cfe/trunk/unittests/StaticAnalyzer/AnalyzerOptionsTest.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/StaticAnalyzer/AnalyzerOptionsTest.cpp?rev=335740&r1=335739&r2=335740&view=diff
>
> ==============================================================================
> --- cfe/trunk/unittests/StaticAnalyzer/AnalyzerOptionsTest.cpp (original)
> +++ cfe/trunk/unittests/StaticAnalyzer/AnalyzerOptionsTest.cpp Wed Jun 27
> 07:56:12 2018
> @@ -1,4 +1,4 @@
> -//===- unittest/Analysis/AnalyzerOptionsTest.cpp - SA Options test
> --------===//
> +//===- unittest/StaticAnalyzer/AnalyzerOptionsTest.cpp - SA Options test
> --===//
>  //
>  //                     The LLVM Compiler Infrastructure
>  //
>
> Modified: cfe/trunk/unittests/StaticAnalyzer/CMakeLists.txt
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/StaticAnalyzer/CMakeLists.txt?rev=335740&r1=335739&r2=335740&view=diff
>
> ==============================================================================
> --- cfe/trunk/unittests/StaticAnalyzer/CMakeLists.txt (original)
> +++ cfe/trunk/unittests/StaticAnalyzer/CMakeLists.txt Wed Jun 27 07:56:12
> 2018
> @@ -4,11 +4,14 @@ set(LLVM_LINK_COMPONENTS
>
>  add_clang_unittest(StaticAnalysisTests
>    AnalyzerOptionsTest.cpp
> +  RegisterCustomCheckersTest.cpp
>    )
>
>  target_link_libraries(StaticAnalysisTests
>    PRIVATE
>    clangBasic
>    clangAnalysis
> -  clangStaticAnalyzerCore
> +  clangStaticAnalyzerCore
> +  clangStaticAnalyzerFrontend
> +  clangTooling
>    )
>
> Added: cfe/trunk/unittests/StaticAnalyzer/RegisterCustomCheckersTest.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/StaticAnalyzer/RegisterCustomCheckersTest.cpp?rev=335740&view=auto
>
> ==============================================================================
> --- cfe/trunk/unittests/StaticAnalyzer/RegisterCustomCheckersTest.cpp
> (added)
> +++ cfe/trunk/unittests/StaticAnalyzer/RegisterCustomCheckersTest.cpp Wed
> Jun 27 07:56:12 2018
> @@ -0,0 +1,80 @@
> +//===- unittests/StaticAnalyzer/RegisterCustomCheckersTest.cpp
> ------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
>
> +//===----------------------------------------------------------------------===//
> +
> +#include "clang/Frontend/CompilerInstance.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/CheckerRegistry.h"
> +#include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h"
> +#include "clang/StaticAnalyzer/Frontend/AnalysisConsumer.h"
> +#include "clang/Tooling/Tooling.h"
> +#include "gtest/gtest.h"
> +
> +namespace clang {
> +namespace ento {
> +namespace {
> +
> +class CustomChecker : public Checker<check::ASTCodeBody> {
> +public:
> +  void checkASTCodeBody(const Decl *D, AnalysisManager &Mgr,
> +                        BugReporter &BR) const {
> +    BR.EmitBasicReport(D, this, "Custom diagnostic",
> categories::LogicError,
> +                       "Custom diagnostic description",
> +                       PathDiagnosticLocation(D, Mgr.getSourceManager()),
> {});
> +  }
> +};
> +
> +class TestAction : public ASTFrontendAction {
> +  class DiagConsumer : public PathDiagnosticConsumer {
> +    llvm::raw_ostream &Output;
> +
> +  public:
> +    DiagConsumer(llvm::raw_ostream &Output) : Output(Output) {}
> +    void FlushDiagnosticsImpl(std::vector<const PathDiagnostic *> &Diags,
> +                              FilesMade *filesMade) override {
> +      for (const auto *PD : Diags)
> +        Output << PD->getCheckName() << ":" << PD->getShortDescription();
> +    }
> +
> +    StringRef getName() const override { return "Test"; }
> +  };
> +
> +  llvm::raw_ostream &DiagsOutput;
> +
> +public:
> +  TestAction(llvm::raw_ostream &DiagsOutput) : DiagsOutput(DiagsOutput) {}
> +
> +  std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance
> &Compiler,
> +                                                 StringRef File) override
> {
> +    std::unique_ptr<AnalysisASTConsumer> AnalysisConsumer =
> +        CreateAnalysisConsumer(Compiler);
> +    AnalysisConsumer->AddDiagnosticConsumer(new
> DiagConsumer(DiagsOutput));
> +    Compiler.getAnalyzerOpts()->CheckersControlList = {
> +        {"custom.CustomChecker", true}};
> +    AnalysisConsumer->AddCheckerRegistrationFn([](CheckerRegistry
> &Registry) {
> +      Registry.addChecker<CustomChecker>("custom.CustomChecker",
> "Description");
> +    });
> +    return AnalysisConsumer;
> +  }
> +};
> +
> +
> +TEST(RegisterCustomCheckers, RegisterChecker) {
> +  std::string Diags;
> +  {
> +    llvm::raw_string_ostream OS(Diags);
> +    EXPECT_TRUE(tooling::runToolOnCode(new TestAction(OS), "void f()
> {;}"));
> +  }
> +  EXPECT_EQ(Diags, "custom.CustomChecker:Custom diagnostic description");
> +}
> +
> +}
> +}
> +}
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>


-- 
--Artem Belevich
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20180627/3c36cde3/attachment-0001.html>


More information about the cfe-commits mailing list