- Respond to review comments: copy options instead of maintaining a
reference, and add more test cases.
http://reviews.llvm.org/D3556
Files:
clang-tidy/ClangTidy.cpp
clang-tidy/ClangTidy.h
clang-tidy/ClangTidyOptions.h
clang-tidy/tool/ClangTidyMain.cpp
test/clang-tidy/temporaries.cpp
Index: clang-tidy/ClangTidy.cpp
===================================================================
--- clang-tidy/ClangTidy.cpp
+++ clang-tidy/ClangTidy.cpp
@@ -173,8 +173,9 @@
} // namespace
ClangTidyASTConsumerFactory::ClangTidyASTConsumerFactory(
- ClangTidyContext &Context)
- : Context(Context), CheckFactories(new ClangTidyCheckFactories) {
+ ClangTidyContext &Context, const ClangTidyOptions &Options)
+ : Context(Context), CheckFactories(new ClangTidyCheckFactories),
+ Options(Options) {
for (ClangTidyModuleRegistry::iterator I = ClangTidyModuleRegistry::begin(),
E = ClangTidyModuleRegistry::end();
I != E; ++I) {
@@ -207,16 +208,21 @@
if (!CheckFactories->empty())
Consumers.push_back(Finder.newASTConsumer());
- AnalyzerOptionsRef Options = Compiler.getAnalyzerOpts();
- Options->CheckersControlList = getCheckersControlList();
- if (!Options->CheckersControlList.empty()) {
- Options->AnalysisStoreOpt = RegionStoreModel;
- Options->AnalysisDiagOpt = PD_NONE;
- Options->AnalyzeNestedBlocks = true;
- Options->eagerlyAssumeBinOpBifurcation = true;
+ AnalyzerOptionsRef AnalyzerOptions = Compiler.getAnalyzerOpts();
+ // FIXME: Remove this option once clang's cfg-temporary-dtors option defaults
+ // to true.
+ AnalyzerOptions->Config["cfg-temporary-dtors"] =
+ Options.AnalyzeTemporaryDtors ? "true" : "false";
+
+ AnalyzerOptions->CheckersControlList = getCheckersControlList();
+ if (!AnalyzerOptions->CheckersControlList.empty()) {
+ AnalyzerOptions->AnalysisStoreOpt = RegionStoreModel;
+ AnalyzerOptions->AnalysisDiagOpt = PD_NONE;
+ AnalyzerOptions->AnalyzeNestedBlocks = true;
+ AnalyzerOptions->eagerlyAssumeBinOpBifurcation = true;
ento::AnalysisASTConsumer *AnalysisConsumer = ento::CreateAnalysisConsumer(
Compiler.getPreprocessor(), Compiler.getFrontendOpts().OutputFile,
- Options, Compiler.getFrontendOpts().Plugins);
+ AnalyzerOptions, Compiler.getFrontendOpts().Plugins);
AnalysisConsumer->AddDiagnosticConsumer(
new AnalyzerDiagnosticConsumer(Context));
Consumers.push_back(AnalysisConsumer);
@@ -288,7 +294,7 @@
std::vector<std::string> getCheckNames(const ClangTidyOptions &Options) {
SmallVector<ClangTidyError, 8> Errors;
clang::tidy::ClangTidyContext Context(&Errors, Options);
- ClangTidyASTConsumerFactory Factory(Context);
+ ClangTidyASTConsumerFactory Factory(Context, Options);
return Factory.getCheckNames();
}
@@ -326,7 +332,7 @@
ClangTidyASTConsumerFactory *ConsumerFactory;
};
- Tool.run(new ActionFactory(new ClangTidyASTConsumerFactory(Context)));
+ Tool.run(new ActionFactory(new ClangTidyASTConsumerFactory(Context, Options)));
}
void handleErrors(SmallVectorImpl<ClangTidyError> &Errors, bool Fix) {
Index: clang-tidy/ClangTidy.h
===================================================================
--- clang-tidy/ClangTidy.h
+++ clang-tidy/ClangTidy.h
@@ -94,7 +94,8 @@
class ClangTidyASTConsumerFactory {
public:
- ClangTidyASTConsumerFactory(ClangTidyContext &Context);
+ ClangTidyASTConsumerFactory(ClangTidyContext &Context,
+ const ClangTidyOptions &Options);
~ClangTidyASTConsumerFactory();
/// \brief Returns an ASTConsumer that runs the specified clang-tidy checks.
@@ -112,6 +113,7 @@
ClangTidyContext &Context;
ast_matchers::MatchFinder Finder;
std::unique_ptr<ClangTidyCheckFactories> CheckFactories;
+ ClangTidyOptions Options;
};
/// \brief Fills the list of check names that are enabled when the provided
Index: clang-tidy/ClangTidyOptions.h
===================================================================
--- clang-tidy/ClangTidyOptions.h
+++ clang-tidy/ClangTidyOptions.h
@@ -18,6 +18,7 @@
ClangTidyOptions() : EnableChecksRegex(".*") {}
std::string EnableChecksRegex;
std::string DisableChecksRegex;
+ bool AnalyzeTemporaryDtors;
};
} // end namespace tidy
Index: clang-tidy/tool/ClangTidyMain.cpp
===================================================================
--- clang-tidy/tool/ClangTidyMain.cpp
+++ clang-tidy/tool/ClangTidyMain.cpp
@@ -46,12 +46,20 @@
cl::desc("List all enabled checks and exit."),
cl::init(false), cl::cat(ClangTidyCategory));
+static cl::opt<bool> AnalyzeTemporaryDtors(
+ "analyze-temporary-dtors",
+ cl::desc("Enable temporary destructor-aware analysis in clang-analyzer- "
+ "checks."),
+ cl::init(false),
+ cl::cat(ClangTidyCategory));
+
int main(int argc, const char **argv) {
CommonOptionsParser OptionsParser(argc, argv, ClangTidyCategory);
clang::tidy::ClangTidyOptions Options;
Options.EnableChecksRegex = Checks;
Options.DisableChecksRegex = DisableChecks;
+ Options.AnalyzeTemporaryDtors = AnalyzeTemporaryDtors;
// FIXME: Allow using --list-checks without positional arguments.
if (ListChecks) {
Index: test/clang-tidy/temporaries.cpp
===================================================================
--- /dev/null
+++ test/clang-tidy/temporaries.cpp
@@ -0,0 +1,26 @@
+// RUN: clang-tidy -checks=clang-analyzer-core.NullDereference -disable-checks='' -analyze-temporary-dtors %s -- > %t.log
+// FileCheck complains if the input file is empty, so add a dummy line.
+// RUN: echo foo >> %t.log
+// RUN: FileCheck %s < %t.log
+
+struct NoReturnDtor {
+ ~NoReturnDtor() __attribute__((noreturn));
+};
+
+extern bool check(const NoReturnDtor &);
+
+// CHECK-NOT: warning
+void testNullPointerDereferencePositive() {
+ int *value = 0;
+ // CHECK: [[@LINE+1]]:10: warning: Dereference of null pointer (loaded from variable 'value') [clang-analyzer-core.NullDereference]
+ *value = 1;
+}
+
+// CHECK-NOT: warning
+void testNullPointerDereference() {
+ int *value = 0;
+ if (check(NoReturnDtor())) {
+ // This unreachable code causes a warning if we don't run with -analyze-temporary-dtors
+ *value = 1;
+ }
+}
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits