[clang-tools-extra] r207652 - Add a clang-tidy flag to support temporary destructor-aware analysis (workaround for bug 15599).

Alex McCarthy alexmc at google.com
Wed Apr 30 07:09:25 PDT 2014


Author: alexmc
Date: Wed Apr 30 09:09:24 2014
New Revision: 207652

URL: http://llvm.org/viewvc/llvm-project?rev=207652&view=rev
Log:
Add a clang-tidy flag to support temporary destructor-aware analysis (workaround for bug 15599).

Reviewers: alexfh

Subscribers: jordan_rose, klimek, djasper, cfe-commits

Differential Revision: http://reviews.llvm.org/D3556

Added:
    clang-tools-extra/trunk/test/clang-tidy/temporaries.cpp
Modified:
    clang-tools-extra/trunk/clang-tidy/ClangTidy.cpp
    clang-tools-extra/trunk/clang-tidy/ClangTidy.h
    clang-tools-extra/trunk/clang-tidy/ClangTidyOptions.h
    clang-tools-extra/trunk/clang-tidy/tool/ClangTidyMain.cpp

Modified: clang-tools-extra/trunk/clang-tidy/ClangTidy.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/ClangTidy.cpp?rev=207652&r1=207651&r2=207652&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/ClangTidy.cpp (original)
+++ clang-tools-extra/trunk/clang-tidy/ClangTidy.cpp Wed Apr 30 09:09:24 2014
@@ -173,8 +173,9 @@ private:
 } // 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 @@ clang::ASTConsumer *ClangTidyASTConsumer
   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 @@ void ClangTidyCheck::setName(StringRef N
 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 @@ void runClangTidy(const ClangTidyOptions
     ClangTidyASTConsumerFactory *ConsumerFactory;
   };
 
-  Tool.run(new ActionFactory(new ClangTidyASTConsumerFactory(Context)));
+  Tool.run(new ActionFactory(new ClangTidyASTConsumerFactory(Context, Options)));
 }
 
 void handleErrors(SmallVectorImpl<ClangTidyError> &Errors, bool Fix) {

Modified: clang-tools-extra/trunk/clang-tidy/ClangTidy.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/ClangTidy.h?rev=207652&r1=207651&r2=207652&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/ClangTidy.h (original)
+++ clang-tools-extra/trunk/clang-tidy/ClangTidy.h Wed Apr 30 09:09:24 2014
@@ -94,7 +94,8 @@ class ClangTidyCheckFactories;
 
 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 @@ private:
   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

Modified: clang-tools-extra/trunk/clang-tidy/ClangTidyOptions.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/ClangTidyOptions.h?rev=207652&r1=207651&r2=207652&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/ClangTidyOptions.h (original)
+++ clang-tools-extra/trunk/clang-tidy/ClangTidyOptions.h Wed Apr 30 09:09:24 2014
@@ -18,6 +18,7 @@ struct ClangTidyOptions {
   ClangTidyOptions() : EnableChecksRegex(".*") {}
   std::string EnableChecksRegex;
   std::string DisableChecksRegex;
+  bool AnalyzeTemporaryDtors;
 };
 
 } // end namespace tidy

Modified: clang-tools-extra/trunk/clang-tidy/tool/ClangTidyMain.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/tool/ClangTidyMain.cpp?rev=207652&r1=207651&r2=207652&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/tool/ClangTidyMain.cpp (original)
+++ clang-tools-extra/trunk/clang-tidy/tool/ClangTidyMain.cpp Wed Apr 30 09:09:24 2014
@@ -46,12 +46,20 @@ static cl::opt<bool> ListChecks("list-ch
                                 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) {

Added: clang-tools-extra/trunk/test/clang-tidy/temporaries.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/temporaries.cpp?rev=207652&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/temporaries.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/temporaries.cpp Wed Apr 30 09:09:24 2014
@@ -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;
+  }
+}





More information about the cfe-commits mailing list