Skip to content

Commit

Permalink
[clang-tidy] Added -fix-errors option
Browse files Browse the repository at this point in the history
Summary:
Added -fix-errors option to allow applying fixes when compiler errors
are present. Without this flag -fix would bail out if there are compiler errors.
This is needed to avoid applying wrong fixes if Clang fails to recover from
compilation errors correctly.

Reviewers: djasper, klimek

Reviewed By: klimek

Subscribers: curdeius, cfe-commits

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

llvm-svn: 221152
  • Loading branch information
alexfh committed Nov 3, 2014
1 parent cf6bfb1 commit 5eac3c6
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 4 deletions.
30 changes: 26 additions & 4 deletions clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp
Expand Up @@ -64,7 +64,7 @@ HeaderFilter("header-filter",

static cl::opt<bool>
SystemHeaders("system-headers",
cl::desc("Display the errors from system headers"),
cl::desc("Display the errors from system headers."),
cl::init(false), cl::cat(ClangTidyCategory));
static cl::opt<std::string>
LineFilter("line-filter",
Expand All @@ -78,8 +78,18 @@ LineFilter("line-filter",
" ]"),
cl::init(""), cl::cat(ClangTidyCategory));

static cl::opt<bool> Fix("fix", cl::desc("Fix detected errors if possible."),
cl::init(false), cl::cat(ClangTidyCategory));
static cl::opt<bool>
Fix("fix", cl::desc("Apply suggested fixes. Without -fix-errors\n"
"clang-tidy will bail out if any compilation\n"
"errors were found."),
cl::init(false), cl::cat(ClangTidyCategory));

static cl::opt<bool>
FixErrors("fix-errors",
cl::desc("Apply suggested fixes even if compilation errors\n"
"were found. If compiler errors have attached\n"
"fix-its, clang-tidy will apply them as well."),
cl::init(false), cl::cat(ClangTidyCategory));

static cl::opt<bool>
ListChecks("list-checks",
Expand Down Expand Up @@ -277,7 +287,15 @@ int clangTidyMain(int argc, const char **argv) {
runClangTidy(std::move(OptionsProvider), OptionsParser.getCompilations(),
OptionsParser.getSourcePathList(), &Errors,
EnableCheckProfile ? &Profile : nullptr);
handleErrors(Errors, Fix);
bool FoundErrors =
std::find_if(Errors.begin(), Errors.end(), [](const ClangTidyError &E) {
return E.DiagLevel == ClangTidyError::Error;
}) != Errors.end();

const bool DisableFixes = Fix && FoundErrors && !FixErrors;

// -fix-errors implies -fix.
handleErrors(Errors, (FixErrors || Fix) && !DisableFixes);

if (!ExportFixes.empty() && !Errors.empty()) {
std::error_code EC;
Expand All @@ -290,6 +308,10 @@ int clangTidyMain(int argc, const char **argv) {
}

printStats(Stats);
if (DisableFixes)
llvm::errs() << "Found compiler errors, but -fix-error was not specified.\n"
"Fixes have NOT been applied.\n\n";

if (EnableCheckProfile)
printProfileData(Profile, llvm::errs());

Expand Down
15 changes: 15 additions & 0 deletions clang-tools-extra/test/clang-tidy/fix-errors.cpp
@@ -0,0 +1,15 @@
// RUN: grep -Ev "// *[A-Z-]+:" %s > %t.cpp
// RUN: clang-tidy %t.cpp -checks='-*,google-explicit-constructor' -fix -- > %t.msg 2>&1
// RUN: FileCheck -input-file=%t.cpp -check-prefix=CHECK-FIX %s
// RUN: FileCheck -input-file=%t.msg -check-prefix=CHECK-MESSAGES %s
// RUN: grep -Ev "// *[A-Z-]+:" %s > %t.cpp
// RUN: clang-tidy %t.cpp -checks='-*,google-explicit-constructor' -fix-errors -- > %t.msg 2>&1
// RUN: FileCheck -input-file=%t.cpp -check-prefix=CHECK-FIX2 %s
// RUN: FileCheck -input-file=%t.msg -check-prefix=CHECK-MESSAGES2 %s

class A { A(int i); }
// CHECK-FIX: class A { A(int i); }{{$}}
// CHECK-MESSAGES: Fixes have NOT been applied.
// CHECK-FIX2: class A { explicit A(int i); };
// CHECK-MESSAGES2: note: FIX-IT applied suggested code changes
// CHECK-MESSAGES2: clang-tidy applied 2 of 2 suggested fixes.

0 comments on commit 5eac3c6

Please sign in to comment.