Ka-Ka created this revision.
Herald added a subscriber: cfe-commits.

Changed the assert and corresponding warning message for conflicting fixes
to only trigger if clang-tidy is run with -fix or -fix-errors.
The Fix and FixErrors variables are now passed as parameters when creating
respective objects.

This is not a finished patch. We need input if there are a more appropriate fix 
of this problem.

Patch by: Henric Karlsson and Björn Pettersson


Repository:
  rC Clang

https://reviews.llvm.org/D55438

Files:
  lib/StaticAnalyzer/Core/ExprEngineC.cpp
  tools/extra/clang-tidy/ClangTidy.cpp
  tools/extra/clang-tidy/ClangTidy.h
  tools/extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp
  tools/extra/clang-tidy/ClangTidyDiagnosticConsumer.h
  tools/extra/clang-tidy/tool/ClangTidyMain.cpp
  tools/extra/test/clang-tidy/clang-tidy-logicalexpr-crash.c

Index: tools/extra/test/clang-tidy/clang-tidy-logicalexpr-crash.c
===================================================================
--- /dev/null
+++ tools/extra/test/clang-tidy/clang-tidy-logicalexpr-crash.c
@@ -0,0 +1,7 @@
+// RUN: clang-tidy -checks='-*,clang-analyzer-*' %s
+
+a;
+fn1() {
+  int b = -a ?: a;
+  (b || 0) && 9;
+}
Index: tools/extra/clang-tidy/tool/ClangTidyMain.cpp
===================================================================
--- tools/extra/clang-tidy/tool/ClangTidyMain.cpp
+++ tools/extra/clang-tidy/tool/ClangTidyMain.cpp
@@ -426,7 +426,7 @@
                            AllowEnablingAnalyzerAlphaCheckers);
   std::vector<ClangTidyError> Errors =
       runClangTidy(Context, OptionsParser.getCompilations(), PathList, BaseFS,
-                   EnableCheckProfile, ProfilePrefix);
+                   (Fix || FixErrors), EnableCheckProfile, ProfilePrefix);
   bool FoundErrors = llvm::find_if(Errors, [](const ClangTidyError &E) {
                        return E.DiagLevel == ClangTidyError::Error;
                      }) != Errors.end();
Index: tools/extra/clang-tidy/ClangTidyDiagnosticConsumer.h
===================================================================
--- tools/extra/clang-tidy/ClangTidyDiagnosticConsumer.h
+++ tools/extra/clang-tidy/ClangTidyDiagnosticConsumer.h
@@ -226,7 +226,8 @@
 class ClangTidyDiagnosticConsumer : public DiagnosticConsumer {
 public:
   ClangTidyDiagnosticConsumer(ClangTidyContext &Ctx,
-                              bool RemoveIncompatibleErrors = true);
+                              bool RemoveIncompatibleErrors = true,
+                              bool FixResolutions = false);
 
   // FIXME: The concept of converting between FixItHints and Replacements is
   // more generic and should be pulled out into a more useful Diagnostics
@@ -252,6 +253,7 @@
 
   ClangTidyContext &Context;
   bool RemoveIncompatibleErrors;
+  bool FixResolutions;
   std::vector<ClangTidyError> Errors;
   std::unique_ptr<llvm::Regex> HeaderFilter;
   bool LastErrorRelatesToUserCode;
Index: tools/extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp
===================================================================
--- tools/extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp
+++ tools/extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp
@@ -33,8 +33,10 @@
 public:
   ClangTidyDiagnosticRenderer(const LangOptions &LangOpts,
                               DiagnosticOptions *DiagOpts,
-                              ClangTidyError &Error)
-      : DiagnosticRenderer(LangOpts, DiagOpts), Error(Error) {}
+                              ClangTidyError &Error,
+                              bool FixResolutions)
+      : DiagnosticRenderer(LangOpts, DiagOpts), Error(Error),
+        FixResolutions(FixResolutions) {}
 
 protected:
   void emitDiagnosticMessage(FullSourceLoc Loc, PresumedLoc PLoc,
@@ -81,10 +83,13 @@
       llvm::Error Err = Error.Fix[Replacement.getFilePath()].add(Replacement);
       // FIXME: better error handling (at least, don't let other replacements be
       // applied).
-      if (Err) {
+      if (Err && FixResolutions) {
         llvm::errs() << "Fix conflicts with existing fix! "
                      << llvm::toString(std::move(Err)) << "\n";
         assert(false && "Fix conflicts with existing fix!");
+      } else if (Err) {
+        // Replacements wont be used for fixing anything.
+        consumeError(std::move(Err));
       }
     }
   }
@@ -104,6 +109,7 @@
 
 private:
   ClangTidyError &Error;
+  bool FixResolutions;
 };
 } // end anonymous namespace
 
@@ -264,10 +270,10 @@
 }
 
 ClangTidyDiagnosticConsumer::ClangTidyDiagnosticConsumer(
-    ClangTidyContext &Ctx, bool RemoveIncompatibleErrors)
+    ClangTidyContext &Ctx, bool RemoveIncompatibleErrors , bool FixResolutions )
     : Context(Ctx), RemoveIncompatibleErrors(RemoveIncompatibleErrors),
-      LastErrorRelatesToUserCode(false), LastErrorPassesLineFilter(false),
-      LastErrorWasIgnored(false) {}
+      FixResolutions(FixResolutions), LastErrorRelatesToUserCode(false),
+      LastErrorPassesLineFilter(false), LastErrorWasIgnored(false) {}
 
 void ClangTidyDiagnosticConsumer::finalizeLastError() {
   if (!Errors.empty()) {
@@ -444,7 +450,7 @@
 
   ClangTidyDiagnosticRenderer Converter(
       Context.getLangOpts(), &Context.DiagEngine->getDiagnosticOptions(),
-      Errors.back());
+      Errors.back(), FixResolutions);
   SmallString<100> Message;
   Info.FormatDiagnostic(Message);
   FullSourceLoc Loc;
Index: tools/extra/clang-tidy/ClangTidy.h
===================================================================
--- tools/extra/clang-tidy/ClangTidy.h
+++ tools/extra/clang-tidy/ClangTidy.h
@@ -235,7 +235,7 @@
              const tooling::CompilationDatabase &Compilations,
              ArrayRef<std::string> InputFiles,
              llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> BaseFS,
-             bool EnableCheckProfile = false,
+             bool FixResolutions, bool EnableCheckProfile = false,
              llvm::StringRef StoreCheckProfile = StringRef());
 
 // FIXME: This interface will need to be significantly extended to be useful.
Index: tools/extra/clang-tidy/ClangTidy.cpp
===================================================================
--- tools/extra/clang-tidy/ClangTidy.cpp
+++ tools/extra/clang-tidy/ClangTidy.cpp
@@ -507,7 +507,8 @@
              const CompilationDatabase &Compilations,
              ArrayRef<std::string> InputFiles,
              llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> BaseFS,
-             bool EnableCheckProfile, llvm::StringRef StoreCheckProfile) {
+             bool FixResolutions, bool EnableCheckProfile,
+             llvm::StringRef StoreCheckProfile) {
   ClangTool Tool(Compilations, InputFiles,
                  std::make_shared<PCHContainerOperations>(), BaseFS);
 
@@ -550,7 +551,7 @@
   Context.setEnableProfiling(EnableCheckProfile);
   Context.setProfileStoragePrefix(StoreCheckProfile);
 
-  ClangTidyDiagnosticConsumer DiagConsumer(Context);
+  ClangTidyDiagnosticConsumer DiagConsumer(Context, true, FixResolutions);
   DiagnosticsEngine DE(new DiagnosticIDs(), new DiagnosticOptions(),
                        &DiagConsumer, /*ShouldOwnClient=*/false);
   Context.setDiagnosticsEngine(&DE);
Index: lib/StaticAnalyzer/Core/ExprEngineC.cpp
===================================================================
--- lib/StaticAnalyzer/Core/ExprEngineC.cpp
+++ lib/StaticAnalyzer/Core/ExprEngineC.cpp
@@ -649,6 +649,12 @@
     (void) P;
     assert(N->pred_size() == 1);
     N = *N->pred_begin();
+    if (N->pred_size() != 1) {
+      // FIXME: The CFG-based reasoning below does not apply.
+      // Do not set the value for the expression. It'd be UnknownVal by default.
+      Bldr.generateNode(B, Pred, state);
+      return;
+    }
   }
   assert(N->pred_size() == 1);
   N = *N->pred_begin();
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to