Index: clang-tidy/ClangTidy.cpp =================================================================== --- clang-tidy/ClangTidy.cpp +++ clang-tidy/ClangTidy.cpp @@ -336,8 +336,9 @@ void handleErrors(const std::vector &Errors, bool Fix) { ErrorReporter Reporter(Fix); for (const ClangTidyError &Error : Errors) { - Reporter.reportDiagnostic(Error.Message, DiagnosticsEngine::Warning, - &Error.Fix); + Reporter.reportDiagnostic( + Error.Message, static_cast(Error.DiagLevel), + &Error.Fix); for (const ClangTidyMessage &Note : Error.Notes) Reporter.reportDiagnostic(Note, DiagnosticsEngine::Note); } Index: clang-tidy/ClangTidyDiagnosticConsumer.h =================================================================== --- clang-tidy/ClangTidyDiagnosticConsumer.h +++ clang-tidy/ClangTidyDiagnosticConsumer.h @@ -49,12 +49,19 @@ /// /// FIXME: Make Diagnostics flexible enough to support this directly. struct ClangTidyError { - ClangTidyError(StringRef CheckName); + enum Level { + Warning = DiagnosticsEngine::Warning, + Error = DiagnosticsEngine::Error + }; + + ClangTidyError(StringRef CheckName, Level DiagLevel); std::string CheckName; ClangTidyMessage Message; tooling::Replacements Fix; SmallVector Notes; + + Level DiagLevel; }; /// \brief Filters checks by name. Index: clang-tidy/ClangTidyDiagnosticConsumer.cpp =================================================================== --- clang-tidy/ClangTidyDiagnosticConsumer.cpp +++ clang-tidy/ClangTidyDiagnosticConsumer.cpp @@ -109,7 +109,9 @@ FileOffset = Sources.getFileOffset(Loc); } -ClangTidyError::ClangTidyError(StringRef CheckName) : CheckName(CheckName) {} +ClangTidyError::ClangTidyError(StringRef CheckName, + ClangTidyError::Level DiagLevel) + : CheckName(CheckName), DiagLevel(DiagLevel) {} // Returns true if GlobList starts with the negative indicator ('-'), removes it // from the GlobList. @@ -214,7 +216,8 @@ void ClangTidyDiagnosticConsumer::finalizeLastError() { if (!Errors.empty()) { ClangTidyError &Error = Errors.back(); - if (!Context.getChecksFilter().isCheckEnabled(Error.CheckName)) { + if (!Context.getChecksFilter().isCheckEnabled(Error.CheckName) && + Error.DiagLevel != ClangTidyError::Error) { ++Context.Stats.ErrorsIgnoredCheckFilter; Errors.pop_back(); } else if (!LastErrorRelatesToUserCode) { @@ -246,7 +249,14 @@ ? ("clang-diagnostic-" + WarningOption).str() : Context.getCheckName(Info.getID()).str(); - Errors.push_back(ClangTidyError(CheckName)); + ClangTidyError::Level Level = ClangTidyError::Warning; + if (DiagLevel == DiagnosticsEngine::Error || + DiagLevel == DiagnosticsEngine::Fatal) { + Level = ClangTidyError::Error; + LastErrorRelatesToUserCode = true; + LastErrorPassesLineFilter = true; + } + Errors.push_back(ClangTidyError(CheckName, Level)); } // FIXME: Provide correct LangOptions for each file. Index: test/clang-tidy/deduplication.cpp =================================================================== --- test/clang-tidy/deduplication.cpp +++ test/clang-tidy/deduplication.cpp @@ -1,12 +1,12 @@ // RUN: clang-tidy -checks='-*,google-explicit-constructor' %s -- | FileCheck %s template -class A { A(T); }; -// CHECK: :[[@LINE-1]]:11: warning: Single-argument constructors must be explicit [google-explicit-constructor] +struct A { A(T); }; +// CHECK: :[[@LINE-1]]:12: warning: Single-argument constructors must be explicit [google-explicit-constructor] // CHECK-NOT: warning: void f() { - A a; - A b; + A a(0); + A b(0); } Index: test/clang-tidy/diagnostic.cpp =================================================================== --- test/clang-tidy/diagnostic.cpp +++ test/clang-tidy/diagnostic.cpp @@ -1,4 +1,4 @@ -// RUN: clang-tidy %s.nonexistent.cpp -- | FileCheck -check-prefix=CHECK1 %s +// RUN: clang-tidy -checks='-*' %s.nonexistent.cpp -- | FileCheck -check-prefix=CHECK1 %s // RUN: clang-tidy -checks='google-explicit-constructor' %s -- -fan-unknown-option | FileCheck -check-prefix=CHECK2 %s // RUN: clang-tidy -checks='-*,google-explicit-constructor,clang-diagnostic-literal-conversion' %s -- -fan-unknown-option | FileCheck -check-prefix=CHECK3 %s // RUN: clang-tidy -checks='-*,clang-diagnostic-macro-redefined' %s -- -DMACRO_FROM_COMMAND_LINE | FileCheck -check-prefix=CHECK4 %s @@ -7,8 +7,8 @@ // CHECK2-NOT: warning // CHECK3-NOT: warning -// CHECK1: warning: error reading '{{.*}}.nonexistent.cpp' -// CHECK2: warning: unknown argument: '-fan-unknown-option' +// CHECK1: error: error reading '{{.*}}.nonexistent.cpp' +// CHECK2: error: unknown argument: '-fan-unknown-option' // CHECK2: :[[@LINE+2]]:9: warning: implicit conversion from 'double' to 'int' changes value // CHECK3: :[[@LINE+1]]:9: warning: implicit conversion from 'double' to 'int' changes value Index: test/clang-tidy/redundant-smartptr-get.cpp =================================================================== --- test/clang-tidy/redundant-smartptr-get.cpp +++ test/clang-tidy/redundant-smartptr-get.cpp @@ -6,20 +6,21 @@ namespace std { template -class unique_ptr { +struct unique_ptr { T& operator*() const; T* operator->() const; T* get() const; }; template -class shared_ptr { +struct shared_ptr { T& operator*() const; T* operator->() const; T* get() const; }; } // namespace std +#define NULL __null struct int_ptr { int* get();