2011-02-15 02:13:31 +08:00
|
|
|
//===--- CheckerRegistration.cpp - Registration for the Analyzer Checkers -===//
|
|
|
|
//
|
2019-01-19 16:50:56 +08:00
|
|
|
// 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
|
2011-02-15 02:13:31 +08:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
|
|
|
// Defines the registration function for the analyzer checkers.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2020-02-28 22:07:50 +08:00
|
|
|
#include "clang/StaticAnalyzer/Frontend/AnalyzerHelpFlags.h"
|
2012-12-04 17:13:33 +08:00
|
|
|
#include "clang/Basic/Diagnostic.h"
|
2020-02-28 22:07:50 +08:00
|
|
|
#include "clang/Frontend/CompilerInstance.h"
|
2012-12-04 17:13:33 +08:00
|
|
|
#include "clang/Frontend/FrontendDiagnostic.h"
|
|
|
|
#include "clang/StaticAnalyzer/Core/AnalyzerOptions.h"
|
2011-02-15 02:13:31 +08:00
|
|
|
#include "clang/StaticAnalyzer/Core/CheckerManager.h"
|
[analyzer][NFC] Move CheckerRegistry from the Core directory to Frontend
ClangCheckerRegistry is a very non-obvious, poorly documented, weird concept.
It derives from CheckerRegistry, and is placed in lib/StaticAnalyzer/Frontend,
whereas it's base is located in lib/StaticAnalyzer/Core. It was, from what I can
imagine, used to circumvent the problem that the registry functions of the
checkers are located in the clangStaticAnalyzerCheckers library, but that
library depends on clangStaticAnalyzerCore. However, clangStaticAnalyzerFrontend
depends on both of those libraries.
One can make the observation however, that CheckerRegistry has no place in Core,
it isn't used there at all! The only place where it is used is Frontend, which
is where it ultimately belongs.
This move implies that since
include/clang/StaticAnalyzer/Checkers/ClangCheckers.h only contained a single function:
class CheckerRegistry;
void registerBuiltinCheckers(CheckerRegistry ®istry);
it had to re purposed, as CheckerRegistry is no longer available to
clangStaticAnalyzerCheckers. It was renamed to BuiltinCheckerRegistration.h,
which actually describes it a lot better -- it does not contain the registration
functions for checkers, but only those generated by the tblgen files.
Differential Revision: https://reviews.llvm.org/D54436
llvm-svn: 349275
2018-12-16 00:23:51 +08:00
|
|
|
#include "clang/StaticAnalyzer/Frontend/CheckerRegistry.h"
|
2012-12-04 17:13:33 +08:00
|
|
|
#include "clang/StaticAnalyzer/Frontend/FrontendActions.h"
|
|
|
|
#include "llvm/ADT/SmallVector.h"
|
2011-02-25 08:09:51 +08:00
|
|
|
#include "llvm/Support/raw_ostream.h"
|
2014-03-09 19:36:40 +08:00
|
|
|
#include <memory>
|
2011-02-15 02:13:31 +08:00
|
|
|
|
|
|
|
using namespace clang;
|
|
|
|
using namespace ento;
|
2011-08-17 12:56:03 +08:00
|
|
|
|
2020-02-28 22:07:50 +08:00
|
|
|
void ento::printCheckerHelp(raw_ostream &out, CompilerInstance &CI) {
|
2020-03-24 02:56:39 +08:00
|
|
|
out << "OVERVIEW: Clang Static Analyzer Checkers List\n\n";
|
|
|
|
out << "USAGE: -analyzer-checker <CHECKER or PACKAGE,...>\n\n";
|
[analyzer][NFC] Tie CheckerRegistry to CheckerManager, allow CheckerManager to be constructed for non-analysis purposes
Its been a while since my CheckerRegistry related patches landed, allow me to
refresh your memory:
During compilation, TblGen turns
clang/include/clang/StaticAnalyzer/Checkers/Checkers.td into
(build directory)/tools/clang/include/clang/StaticAnalyzer/Checkers/Checkers.inc.
This is a file that contains the full name of the checkers, their options, etc.
The class that is responsible for parsing this file is CheckerRegistry. The job
of this class is to establish what checkers are available for the analyzer (even
from plugins and statically linked but non-tblgen generated files!), and
calculate which ones should be turned on according to the analyzer's invocation.
CheckerManager is the class that is responsible for the construction and storage
of checkers. This process works by first creating a CheckerRegistry object, and
passing itself to CheckerRegistry::initializeManager(CheckerManager&), which
will call the checker registry functions (for example registerMallocChecker) on
it.
The big problem here is that these two classes lie in two different libraries,
so their interaction is pretty awkward. This used to be far worse, but I
refactored much of it, which made things better but nowhere near perfect.
---
This patch changes how the above mentioned two classes interact. CheckerRegistry
is mainly used by CheckerManager, and they are so intertwined, it makes a lot of
sense to turn in into a field, instead of a one-time local variable. This has
additional benefits: much of the information that CheckerRegistry conveniently
holds is no longer thrown away right after the analyzer's initialization, and
opens the possibility to pass CheckerManager in the shouldRegister* function
rather then LangOptions (D75271).
There are a few problems with this. CheckerManager isn't the only user, when we
honor help flags like -analyzer-checker-help, we only have access to a
CompilerInstance class, that is before the point of parsing the AST.
CheckerManager makes little sense without ASTContext, so I made some changes and
added new constructors to make it constructible for the use of help flags.
Differential Revision: https://reviews.llvm.org/D75360
2020-02-28 22:07:50 +08:00
|
|
|
|
2020-02-28 22:07:50 +08:00
|
|
|
auto CheckerMgr = std::make_unique<CheckerManager>(
|
|
|
|
*CI.getAnalyzerOpts(), CI.getLangOpts(), CI.getDiagnostics(),
|
|
|
|
CI.getFrontendOpts().Plugins);
|
|
|
|
|
[analyzer][NFC] Move the data structures from CheckerRegistry to the Core library
If you were around the analyzer for a while now, you must've seen a lot of
patches that awkwardly puts code from one library to the other:
* D75360 moves the constructors of CheckerManager, which lies in the Core
library, to the Frontend library. Most the patch itself was a struggle along
the library lines.
* D78126 had to be reverted because dependency information would be utilized
in the Core library, but the actual data lied in the frontend.
D78126#inline-751477 touches on this issue as well.
This stems from the often mentioned problem: the Frontend library depends on
Core and Checkers, Checkers depends on Core. The checker registry functions
(`registerMallocChecker`, etc) lie in the Checkers library in order to keep each
checker its own module. What this implies is that checker registration cannot
take place in the Core, but the Core might still want to use the data that
results from it (which checker/package is enabled, dependencies, etc).
D54436 was the patch that initiated this. Back in the days when CheckerRegistry
was super dumb and buggy, it implemented a non-documented solution to this
problem by keeping the data in the Core, and leaving the logic in the Frontend.
At the time when the patch landed, the merger to the Frontend made sense,
because the data hadn't been utilized anywhere, and the whole workaround without
any documentation made little sense to me.
So, lets put the data back where it belongs, in the Core library. This patch
introduces `CheckerRegistryData`, and turns `CheckerRegistry` into a short lived
wrapper around this data that implements the logic of checker registration. The
data is tied to CheckerManager because it is required to parse it.
Side note: I can't help but cringe at the fact how ridiculously awkward the
library lines are. I feel like I'm thinking too much inside the box, but I guess
this is just the price of keeping the checkers so modularized.
Differential Revision: https://reviews.llvm.org/D82585
2020-06-19 03:40:43 +08:00
|
|
|
CheckerMgr->getCheckerRegistryData().printCheckerWithDescList(
|
|
|
|
*CI.getAnalyzerOpts(), out);
|
2016-08-08 21:41:04 +08:00
|
|
|
}
|
2018-11-02 23:59:37 +08:00
|
|
|
|
2020-02-28 22:07:50 +08:00
|
|
|
void ento::printEnabledCheckerList(raw_ostream &out, CompilerInstance &CI) {
|
2020-03-24 02:56:39 +08:00
|
|
|
out << "OVERVIEW: Clang Static Analyzer Enabled Checkers List\n\n";
|
[analyzer][NFC] Tie CheckerRegistry to CheckerManager, allow CheckerManager to be constructed for non-analysis purposes
Its been a while since my CheckerRegistry related patches landed, allow me to
refresh your memory:
During compilation, TblGen turns
clang/include/clang/StaticAnalyzer/Checkers/Checkers.td into
(build directory)/tools/clang/include/clang/StaticAnalyzer/Checkers/Checkers.inc.
This is a file that contains the full name of the checkers, their options, etc.
The class that is responsible for parsing this file is CheckerRegistry. The job
of this class is to establish what checkers are available for the analyzer (even
from plugins and statically linked but non-tblgen generated files!), and
calculate which ones should be turned on according to the analyzer's invocation.
CheckerManager is the class that is responsible for the construction and storage
of checkers. This process works by first creating a CheckerRegistry object, and
passing itself to CheckerRegistry::initializeManager(CheckerManager&), which
will call the checker registry functions (for example registerMallocChecker) on
it.
The big problem here is that these two classes lie in two different libraries,
so their interaction is pretty awkward. This used to be far worse, but I
refactored much of it, which made things better but nowhere near perfect.
---
This patch changes how the above mentioned two classes interact. CheckerRegistry
is mainly used by CheckerManager, and they are so intertwined, it makes a lot of
sense to turn in into a field, instead of a one-time local variable. This has
additional benefits: much of the information that CheckerRegistry conveniently
holds is no longer thrown away right after the analyzer's initialization, and
opens the possibility to pass CheckerManager in the shouldRegister* function
rather then LangOptions (D75271).
There are a few problems with this. CheckerManager isn't the only user, when we
honor help flags like -analyzer-checker-help, we only have access to a
CompilerInstance class, that is before the point of parsing the AST.
CheckerManager makes little sense without ASTContext, so I made some changes and
added new constructors to make it constructible for the use of help flags.
Differential Revision: https://reviews.llvm.org/D75360
2020-02-28 22:07:50 +08:00
|
|
|
|
2020-02-28 22:07:50 +08:00
|
|
|
auto CheckerMgr = std::make_unique<CheckerManager>(
|
|
|
|
*CI.getAnalyzerOpts(), CI.getLangOpts(), CI.getDiagnostics(),
|
|
|
|
CI.getFrontendOpts().Plugins);
|
|
|
|
|
[analyzer][NFC] Move the data structures from CheckerRegistry to the Core library
If you were around the analyzer for a while now, you must've seen a lot of
patches that awkwardly puts code from one library to the other:
* D75360 moves the constructors of CheckerManager, which lies in the Core
library, to the Frontend library. Most the patch itself was a struggle along
the library lines.
* D78126 had to be reverted because dependency information would be utilized
in the Core library, but the actual data lied in the frontend.
D78126#inline-751477 touches on this issue as well.
This stems from the often mentioned problem: the Frontend library depends on
Core and Checkers, Checkers depends on Core. The checker registry functions
(`registerMallocChecker`, etc) lie in the Checkers library in order to keep each
checker its own module. What this implies is that checker registration cannot
take place in the Core, but the Core might still want to use the data that
results from it (which checker/package is enabled, dependencies, etc).
D54436 was the patch that initiated this. Back in the days when CheckerRegistry
was super dumb and buggy, it implemented a non-documented solution to this
problem by keeping the data in the Core, and leaving the logic in the Frontend.
At the time when the patch landed, the merger to the Frontend made sense,
because the data hadn't been utilized anywhere, and the whole workaround without
any documentation made little sense to me.
So, lets put the data back where it belongs, in the Core library. This patch
introduces `CheckerRegistryData`, and turns `CheckerRegistry` into a short lived
wrapper around this data that implements the logic of checker registration. The
data is tied to CheckerManager because it is required to parse it.
Side note: I can't help but cringe at the fact how ridiculously awkward the
library lines are. I feel like I'm thinking too much inside the box, but I guess
this is just the price of keeping the checkers so modularized.
Differential Revision: https://reviews.llvm.org/D82585
2020-06-19 03:40:43 +08:00
|
|
|
CheckerMgr->getCheckerRegistryData().printEnabledCheckerList(out);
|
2020-03-24 02:56:39 +08:00
|
|
|
}
|
[analyzer][NFC] Tie CheckerRegistry to CheckerManager, allow CheckerManager to be constructed for non-analysis purposes
Its been a while since my CheckerRegistry related patches landed, allow me to
refresh your memory:
During compilation, TblGen turns
clang/include/clang/StaticAnalyzer/Checkers/Checkers.td into
(build directory)/tools/clang/include/clang/StaticAnalyzer/Checkers/Checkers.inc.
This is a file that contains the full name of the checkers, their options, etc.
The class that is responsible for parsing this file is CheckerRegistry. The job
of this class is to establish what checkers are available for the analyzer (even
from plugins and statically linked but non-tblgen generated files!), and
calculate which ones should be turned on according to the analyzer's invocation.
CheckerManager is the class that is responsible for the construction and storage
of checkers. This process works by first creating a CheckerRegistry object, and
passing itself to CheckerRegistry::initializeManager(CheckerManager&), which
will call the checker registry functions (for example registerMallocChecker) on
it.
The big problem here is that these two classes lie in two different libraries,
so their interaction is pretty awkward. This used to be far worse, but I
refactored much of it, which made things better but nowhere near perfect.
---
This patch changes how the above mentioned two classes interact. CheckerRegistry
is mainly used by CheckerManager, and they are so intertwined, it makes a lot of
sense to turn in into a field, instead of a one-time local variable. This has
additional benefits: much of the information that CheckerRegistry conveniently
holds is no longer thrown away right after the analyzer's initialization, and
opens the possibility to pass CheckerManager in the shouldRegister* function
rather then LangOptions (D75271).
There are a few problems with this. CheckerManager isn't the only user, when we
honor help flags like -analyzer-checker-help, we only have access to a
CompilerInstance class, that is before the point of parsing the AST.
CheckerManager makes little sense without ASTContext, so I made some changes and
added new constructors to make it constructible for the use of help flags.
Differential Revision: https://reviews.llvm.org/D75360
2020-02-28 22:07:50 +08:00
|
|
|
|
2020-02-28 22:07:50 +08:00
|
|
|
void ento::printCheckerConfigList(raw_ostream &out, CompilerInstance &CI) {
|
|
|
|
|
|
|
|
auto CheckerMgr = std::make_unique<CheckerManager>(
|
|
|
|
*CI.getAnalyzerOpts(), CI.getLangOpts(), CI.getDiagnostics(),
|
|
|
|
CI.getFrontendOpts().Plugins);
|
|
|
|
|
[analyzer][NFC] Move the data structures from CheckerRegistry to the Core library
If you were around the analyzer for a while now, you must've seen a lot of
patches that awkwardly puts code from one library to the other:
* D75360 moves the constructors of CheckerManager, which lies in the Core
library, to the Frontend library. Most the patch itself was a struggle along
the library lines.
* D78126 had to be reverted because dependency information would be utilized
in the Core library, but the actual data lied in the frontend.
D78126#inline-751477 touches on this issue as well.
This stems from the often mentioned problem: the Frontend library depends on
Core and Checkers, Checkers depends on Core. The checker registry functions
(`registerMallocChecker`, etc) lie in the Checkers library in order to keep each
checker its own module. What this implies is that checker registration cannot
take place in the Core, but the Core might still want to use the data that
results from it (which checker/package is enabled, dependencies, etc).
D54436 was the patch that initiated this. Back in the days when CheckerRegistry
was super dumb and buggy, it implemented a non-documented solution to this
problem by keeping the data in the Core, and leaving the logic in the Frontend.
At the time when the patch landed, the merger to the Frontend made sense,
because the data hadn't been utilized anywhere, and the whole workaround without
any documentation made little sense to me.
So, lets put the data back where it belongs, in the Core library. This patch
introduces `CheckerRegistryData`, and turns `CheckerRegistry` into a short lived
wrapper around this data that implements the logic of checker registration. The
data is tied to CheckerManager because it is required to parse it.
Side note: I can't help but cringe at the fact how ridiculously awkward the
library lines are. I feel like I'm thinking too much inside the box, but I guess
this is just the price of keeping the checkers so modularized.
Differential Revision: https://reviews.llvm.org/D82585
2020-06-19 03:40:43 +08:00
|
|
|
CheckerMgr->getCheckerRegistryData().printCheckerOptionList(
|
|
|
|
*CI.getAnalyzerOpts(), out);
|
2019-05-24 04:47:28 +08:00
|
|
|
}
|
|
|
|
|
2018-11-02 23:59:37 +08:00
|
|
|
void ento::printAnalyzerConfigList(raw_ostream &out) {
|
2019-08-15 16:53:16 +08:00
|
|
|
// FIXME: This message sounds scary, should be scary, but incorrectly states
|
|
|
|
// that all configs are super dangerous. In reality, many of them should be
|
|
|
|
// accessible to the user. We should create a user-facing subset of config
|
|
|
|
// options under a different frontend flag.
|
|
|
|
out << R"(
|
|
|
|
OVERVIEW: Clang Static Analyzer -analyzer-config Option List
|
|
|
|
|
|
|
|
The following list of configurations are meant for development purposes only, as
|
|
|
|
some of the variables they define are set to result in the most optimal
|
|
|
|
analysis. Setting them to other values may drastically change how the analyzer
|
|
|
|
behaves, and may even result in instabilities, crashes!
|
|
|
|
|
|
|
|
USAGE: -analyzer-config <OPTION1=VALUE,OPTION2=VALUE,...>
|
|
|
|
-analyzer-config OPTION1=VALUE, -analyzer-config OPTION2=VALUE, ...
|
|
|
|
OPTIONS:
|
|
|
|
)";
|
2018-11-02 23:59:37 +08:00
|
|
|
|
|
|
|
using OptionAndDescriptionTy = std::pair<StringRef, std::string>;
|
|
|
|
OptionAndDescriptionTy PrintableOptions[] = {
|
|
|
|
#define ANALYZER_OPTION(TYPE, NAME, CMDFLAG, DESC, DEFAULT_VAL) \
|
|
|
|
{ \
|
|
|
|
CMDFLAG, \
|
|
|
|
llvm::Twine(llvm::Twine() + "(" + \
|
2018-11-03 03:48:56 +08:00
|
|
|
(StringRef(#TYPE) == "StringRef" ? "string" : #TYPE ) + \
|
|
|
|
") " DESC \
|
2018-11-02 23:59:37 +08:00
|
|
|
" (default: " #DEFAULT_VAL ")").str() \
|
|
|
|
},
|
|
|
|
|
|
|
|
#define ANALYZER_OPTION_DEPENDS_ON_USER_MODE(TYPE, NAME, CMDFLAG, DESC, \
|
|
|
|
SHALLOW_VAL, DEEP_VAL) \
|
|
|
|
{ \
|
|
|
|
CMDFLAG, \
|
|
|
|
llvm::Twine(llvm::Twine() + "(" + \
|
2018-11-03 03:48:56 +08:00
|
|
|
(StringRef(#TYPE) == "StringRef" ? "string" : #TYPE ) + \
|
|
|
|
") " DESC \
|
2018-11-02 23:59:37 +08:00
|
|
|
" (default: " #SHALLOW_VAL " in shallow mode, " #DEEP_VAL \
|
|
|
|
" in deep mode)").str() \
|
|
|
|
},
|
|
|
|
#include "clang/StaticAnalyzer/Core/AnalyzerOptions.def"
|
|
|
|
#undef ANALYZER_OPTION
|
|
|
|
#undef ANALYZER_OPTION_DEPENDS_ON_USER_MODE
|
|
|
|
};
|
|
|
|
|
|
|
|
llvm::sort(PrintableOptions, [](const OptionAndDescriptionTy &LHS,
|
|
|
|
const OptionAndDescriptionTy &RHS) {
|
|
|
|
return LHS.first < RHS.first;
|
|
|
|
});
|
|
|
|
|
|
|
|
for (const auto &Pair : PrintableOptions) {
|
2019-05-24 04:47:28 +08:00
|
|
|
AnalyzerOptions::printFormattedEntry(out, Pair, /*InitialPad*/ 2,
|
|
|
|
/*EntryWidth*/ 30,
|
|
|
|
/*MinLineWidth*/ 70);
|
|
|
|
out << "\n\n";
|
2018-11-02 23:59:37 +08:00
|
|
|
}
|
|
|
|
}
|