Skip to content

Commit

Permalink
Clang style plugin: add warn-only option and use it on Windows
Browse files Browse the repository at this point in the history
This will allow us to flip a flag to enable warnings-as-errors once
the Windows code is cleaned up enough without building a new plugin
binary.

Also, try not to compute the diagnostic level in multiple places.

BUG=467287, 483065

Review URL: https://codereview.chromium.org/1117163002

Cr-Commit-Position: refs/heads/master@{#327852}
  • Loading branch information
zmodem authored and Commit bot committed May 1, 2015
1 parent e0ee6eb commit a7ae971
Show file tree
Hide file tree
Showing 12 changed files with 84 additions and 30 deletions.
8 changes: 7 additions & 1 deletion build/common.gypi
Original file line number Diff line number Diff line change
Expand Up @@ -2173,17 +2173,23 @@
],
},
'clang_dynlib_flags%': '-Xclang -load -Xclang <(clang_lib_path) ',
'clang_plugin_args%': '',
}, { # OS == "win"
# On Windows, the plugin is built directly into clang, so there's
# no need to load it dynamically.
'clang_dynlib_flags%': '',

# Don't error on plugin warnings on Windows until pre-existing warnings
# are cleaned up. https://crbug.com/467287
'clang_plugin_args%': '-Xclang -plugin-arg-find-bad-constructs -Xclang warn-only',
}]
],
},
# If you change these, also change build/config/clang/BUILD.gn.
'clang_chrome_plugins_flags%':
'<(clang_dynlib_flags)'
'-Xclang -add-plugin -Xclang find-bad-constructs',
'-Xclang -add-plugin -Xclang find-bad-constructs '
'<(clang_plugin_args)',
}],
['asan==1 or msan==1 or lsan==1 or tsan==1', {
'clang%': 1,
Expand Down
10 changes: 10 additions & 0 deletions build/config/clang/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,16 @@ config("find_bad_constructs") {
]
}

if (is_win) {
# Don't error on plugin warnings on Windows until pre-existing warnings
# are cleaned up. https://crbug.com/467287
cflags += [
"-Xclang",
"-plugin-arg-find-bad-constructs",
"-Xclang warn-only",
]
}

cflags += [
"-Xclang",
"-add-plugin",
Expand Down
28 changes: 18 additions & 10 deletions tools/clang/plugins/ChromeClassTester.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#endif

using namespace clang;
using chrome_checker::Options;

namespace {

Expand All @@ -30,8 +31,10 @@ bool ends_with(const std::string& one, const std::string& two) {

} // namespace

ChromeClassTester::ChromeClassTester(CompilerInstance& instance)
: instance_(instance),
ChromeClassTester::ChromeClassTester(CompilerInstance& instance,
const Options& options)
: options_(options),
instance_(instance),
diagnostic_(instance.getDiagnostics()) {
BuildBannedLists();
}
Expand Down Expand Up @@ -95,16 +98,13 @@ void ChromeClassTester::emitWarning(SourceLocation loc,
std::string err;
err = "[chromium-style] ";
err += raw_error;
// TODO(dcheng): Re-enable -Werror for these diagnostics on Windows once all
// the pre-existing warnings are cleaned up. https://crbug.com/467287
DiagnosticIDs::Level level =
#if !defined(LLVM_ON_WIN32)
diagnostic().getWarningsAsErrors() ?
DiagnosticIDs::Error :
#endif
DiagnosticIDs::Warning;

DiagnosticIDs::Level level = getErrorLevel() == DiagnosticsEngine::Error
? DiagnosticIDs::Error : DiagnosticIDs::Warning;

unsigned id = diagnostic().getDiagnosticIDs()->getCustomDiagID(level, err);
DiagnosticBuilder builder = diagnostic().Report(full, id);

}

bool ChromeClassTester::InBannedDirectory(SourceLocation loc) {
Expand Down Expand Up @@ -311,3 +311,11 @@ bool ChromeClassTester::GetFilename(SourceLocation loc,
*filename = ploc.getFilename();
return true;
}

DiagnosticsEngine::Level ChromeClassTester::getErrorLevel() {
if (options_.warn_only)
return DiagnosticsEngine::Warning;

return diagnostic().getWarningsAsErrors() ? DiagnosticsEngine::Error
: DiagnosticsEngine::Warning;
}
9 changes: 8 additions & 1 deletion tools/clang/plugins/ChromeClassTester.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <set>
#include <vector>

#include "Options.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/AST/TypeLoc.h"
#include "clang/Frontend/CompilerInstance.h"
Expand All @@ -16,7 +17,8 @@
// headers to subclasses which implement CheckChromeClass().
class ChromeClassTester : public clang::ASTConsumer {
public:
explicit ChromeClassTester(clang::CompilerInstance& instance);
ChromeClassTester(clang::CompilerInstance& instance,
const chrome_checker::Options& options);
virtual ~ChromeClassTester();

// clang::ASTConsumer:
Expand All @@ -25,6 +27,8 @@ class ChromeClassTester : public clang::ASTConsumer {

void CheckTag(clang::TagDecl*);

clang::DiagnosticsEngine::Level getErrorLevel();

protected:
clang::CompilerInstance& instance() { return instance_; }
clang::DiagnosticsEngine& diagnostic() { return diagnostic_; }
Expand All @@ -50,6 +54,9 @@ class ChromeClassTester : public clang::ASTConsumer {
// implementation (.cc, .cpp, .mm) file.
bool InImplementationFile(clang::SourceLocation location);

// Options.
const chrome_checker::Options options_;

private:
void BuildBannedLists();

Expand Down
2 changes: 2 additions & 0 deletions tools/clang/plugins/FindBadConstructsAction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ bool FindBadConstructsAction::ParseArgs(const CompilerInstance& instance,
options_.with_ast_visitor = true;
} else if (args[i] == "check-templates") {
options_.check_templates = true;
} else if (args[i] == "warn-only") {
options_.warn_only = true;
} else {
parsed = false;
llvm::errs() << "Unknown clang plugin argument: " << args[i] << "\n";
Expand Down
15 changes: 1 addition & 14 deletions tools/clang/plugins/FindBadConstructsConsumer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ bool IsPodOrTemplateType(const CXXRecordDecl& record) {

FindBadConstructsConsumer::FindBadConstructsConsumer(CompilerInstance& instance,
const Options& options)
: ChromeClassTester(instance), options_(options) {
: ChromeClassTester(instance, options) {
// Messages for virtual method specifiers.
diag_method_requires_override_ =
diagnostic().getCustomDiagID(getErrorLevel(), kMethodRequiresOverride);
Expand Down Expand Up @@ -593,19 +593,6 @@ FindBadConstructsConsumer::CheckRecordForRefcountIssue(
return None;
}

// Adds either a warning or error, based on the current handling of
// -Werror.
DiagnosticsEngine::Level FindBadConstructsConsumer::getErrorLevel() {
#if defined(LLVM_ON_WIN32)
// TODO(dcheng): Re-enable -Werror for these diagnostics on Windows once all
// the pre-existing warnings are cleaned up. https://crbug.com/467287
return DiagnosticsEngine::Warning;
#else
return diagnostic().getWarningsAsErrors() ? DiagnosticsEngine::Error
: DiagnosticsEngine::Warning;
#endif
}

// Returns true if |base| specifies one of the Chromium reference counted
// classes (base::RefCounted / base::RefCountedThreadSafe).
bool FindBadConstructsConsumer::IsRefCountedCallback(
Expand Down
3 changes: 0 additions & 3 deletions tools/clang/plugins/FindBadConstructsConsumer.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,6 @@ class FindBadConstructsConsumer
static RefcountIssue CheckRecordForRefcountIssue(
const clang::CXXRecordDecl* record,
clang::SourceLocation& loc);
clang::DiagnosticsEngine::Level getErrorLevel();
static bool IsRefCountedCallback(const clang::CXXBaseSpecifier* base,
clang::CXXBasePath& path,
void* user_data);
Expand All @@ -86,8 +85,6 @@ class FindBadConstructsConsumer
void CheckWeakPtrFactoryMembers(clang::SourceLocation record_location,
clang::CXXRecordDecl* record);

const Options options_;

unsigned diag_method_requires_override_;
unsigned diag_redundant_virtual_specifier_;
unsigned diag_base_method_virtual_and_final_;
Expand Down
4 changes: 3 additions & 1 deletion tools/clang/plugins/Options.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,14 @@ struct Options {
: check_base_classes(false),
check_enum_last_value(false),
with_ast_visitor(false),
check_templates(false) {}
check_templates(false),
warn_only(false) {}

bool check_base_classes;
bool check_enum_last_value;
bool with_ast_visitor;
bool check_templates;
bool warn_only;
};

} // namespace chrome_checker
Expand Down
5 changes: 5 additions & 0 deletions tools/clang/plugins/tests/warn_only.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// Copyright (c) 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "warn_only.h"
1 change: 1 addition & 0 deletions tools/clang/plugins/tests/warn_only.flags
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
-Werror -Xclang -plugin-arg-find-bad-constructs -Xclang warn-only
21 changes: 21 additions & 0 deletions tools/clang/plugins/tests/warn_only.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Copyright (c) 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef WARN_ONLY_H_
#define WARN_ONLY_H_

#include <string>
#include <vector>

class InlineCtors {
public:
InlineCtors() {}
~InlineCtors() {}

private:
std::vector<int> one_;
std::vector<std::string> two_;
};

#endif // WARN_ONLY_H_
8 changes: 8 additions & 0 deletions tools/clang/plugins/tests/warn_only.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
In file included from warn_only.cpp:5:
./warn_only.h:13:3: warning: [chromium-style] Complex constructor has an inlined body.
InlineCtors() {}
^
./warn_only.h:14:3: warning: [chromium-style] Complex destructor has an inline body.
~InlineCtors() {}
^
2 warnings generated.

0 comments on commit a7ae971

Please sign in to comment.