forked from OSchip/llvm-project
Disable clang-tidy warnings from system macros
Currently, it's inconsistent that warnings are disabled if they come from system headers, unless they come from macros. Typically a user cannot act upon these warnings coming from system macros, so clang-tidy should ignore them unless the user specifically requests warnings from system headers via the corresponding configuration. This change broke the ProTypeVarargCheck check, because it was checking for the usage of va_arg indirectly, expanding it (it's a system macro) to detect the usage of __builtin_va_arg. The check has been fixed by checking directly what the rule is about: "do not use va_arg", by adding a PP callback that checks if any macro with name "va_arg" is expanded. The old AST matcher is still kept for compatibility with Windows. Add unit test that ensures warnings from macros are disabled when not using the -system-headers flag. Document the change in the Release Notes. Differential Revision: https://reviews.llvm.org/D116378
This commit is contained in:
parent
031d3ece3f
commit
670de10f9d
|
@ -719,7 +719,7 @@ void ClangTidyDiagnosticConsumer::checkFilters(SourceLocation Location,
|
|||
}
|
||||
|
||||
if (!*Context.getOptions().SystemHeaders &&
|
||||
Sources.isInSystemHeader(Location))
|
||||
(Sources.isInSystemHeader(Location) || Sources.isInSystemMacro(Location)))
|
||||
return;
|
||||
|
||||
// FIXME: We start with a conservative approach here, but the actual type of
|
||||
|
|
|
@ -11,6 +11,9 @@
|
|||
#include "clang/ASTMatchers/ASTMatchFinder.h"
|
||||
#include "clang/ASTMatchers/ASTMatchers.h"
|
||||
#include "clang/Basic/TargetInfo.h"
|
||||
#include "clang/Lex/PPCallbacks.h"
|
||||
#include "clang/Lex/Preprocessor.h"
|
||||
#include "clang/Lex/Token.h"
|
||||
|
||||
using namespace clang::ast_matchers;
|
||||
|
||||
|
@ -57,6 +60,10 @@ static constexpr StringRef AllowedVariadics[] = {
|
|||
// clang-format on
|
||||
};
|
||||
|
||||
static constexpr StringRef VaArgWarningMessage =
|
||||
"do not use va_arg to define c-style vararg functions; "
|
||||
"use variadic templates instead";
|
||||
|
||||
namespace {
|
||||
AST_MATCHER(QualType, isVAList) {
|
||||
ASTContext &Context = Finder->getASTContext();
|
||||
|
@ -106,6 +113,21 @@ AST_MATCHER_P(AdjustedType, hasOriginalType,
|
|||
ast_matchers::internal::Matcher<QualType>, InnerType) {
|
||||
return InnerType.matches(Node.getOriginalType(), Finder, Builder);
|
||||
}
|
||||
|
||||
class VaArgPPCallbacks : public PPCallbacks {
|
||||
public:
|
||||
VaArgPPCallbacks(ProTypeVarargCheck *Check) : Check(Check) {}
|
||||
|
||||
void MacroExpands(const Token &MacroNameTok, const MacroDefinition &MD,
|
||||
SourceRange Range, const MacroArgs *Args) override {
|
||||
if (MacroNameTok.getIdentifierInfo()->getName() == "va_arg") {
|
||||
Check->diag(MacroNameTok.getLocation(), VaArgWarningMessage);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
ProTypeVarargCheck *Check;
|
||||
};
|
||||
} // namespace
|
||||
|
||||
void ProTypeVarargCheck::registerMatchers(MatchFinder *Finder) {
|
||||
|
@ -125,6 +147,12 @@ void ProTypeVarargCheck::registerMatchers(MatchFinder *Finder) {
|
|||
this);
|
||||
}
|
||||
|
||||
void ProTypeVarargCheck::registerPPCallbacks(const SourceManager &SM,
|
||||
Preprocessor *PP,
|
||||
Preprocessor *ModuleExpanderPP) {
|
||||
PP->addPPCallbacks(std::make_unique<VaArgPPCallbacks>(this));
|
||||
}
|
||||
|
||||
static bool hasSingleVariadicArgumentWithValue(const CallExpr *C, uint64_t I) {
|
||||
const auto *FDecl = dyn_cast<FunctionDecl>(C->getCalleeDecl());
|
||||
if (!FDecl)
|
||||
|
@ -153,9 +181,7 @@ void ProTypeVarargCheck::check(const MatchFinder::MatchResult &Result) {
|
|||
}
|
||||
|
||||
if (const auto *Matched = Result.Nodes.getNodeAs<Expr>("va_use")) {
|
||||
diag(Matched->getExprLoc(),
|
||||
"do not use va_arg to define c-style vararg functions; "
|
||||
"use variadic templates instead");
|
||||
diag(Matched->getExprLoc(), VaArgWarningMessage);
|
||||
}
|
||||
|
||||
if (const auto *Matched = Result.Nodes.getNodeAs<VarDecl>("va_list")) {
|
||||
|
|
|
@ -28,6 +28,8 @@ public:
|
|||
return LangOpts.CPlusPlus;
|
||||
}
|
||||
void registerMatchers(ast_matchers::MatchFinder *Finder) override;
|
||||
void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP,
|
||||
Preprocessor *ModuleExpanderPP) override;
|
||||
void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
|
||||
};
|
||||
|
||||
|
|
|
@ -67,6 +67,9 @@ The improvements are...
|
|||
Improvements to clang-tidy
|
||||
--------------------------
|
||||
|
||||
- Ignore warnings from macros defined in system headers, if not using the
|
||||
`-system-headers` flag.
|
||||
|
||||
- Added support for globbing in `NOLINT*` expressions, to simplify suppressing
|
||||
multiple warnings in the same line.
|
||||
|
||||
|
|
|
@ -1 +1,3 @@
|
|||
class A0 { A0(int); };
|
||||
|
||||
#define TO_FLOAT_PTR(x) ((float *)(x))
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
// file-filter\header*.h due to code order between '/' and '\\'.
|
||||
// RUN: clang-tidy -checks='-*,google-explicit-constructor' -header-filter='.*' -system-headers %s -- -I %S/Inputs/file-filter/system/.. -isystem %S/Inputs/file-filter/system 2>&1 | FileCheck --check-prefix=CHECK4 %s
|
||||
// RUN: clang-tidy -checks='-*,google-explicit-constructor' -header-filter='.*' -system-headers -quiet %s -- -I %S/Inputs/file-filter/system/.. -isystem %S/Inputs/file-filter/system 2>&1 | FileCheck --check-prefix=CHECK4-QUIET %s
|
||||
// RUN: clang-tidy -checks='-*,cppcoreguidelines-pro-type-cstyle-cast' -header-filter='.*' -system-headers %s -- -I %S/Inputs/file-filter/system/.. -isystem %S/Inputs/file-filter/system 2>&1 | FileCheck --check-prefix=CHECK5 %s
|
||||
// RUN: clang-tidy -checks='-*,cppcoreguidelines-pro-type-cstyle-cast' -header-filter='.*' %s -- -I %S/Inputs/file-filter/system/.. -isystem %S/Inputs/file-filter/system 2>&1 | FileCheck --check-prefix=CHECK5-NO-SYSTEM-HEADERS %s
|
||||
|
||||
#include "header1.h"
|
||||
// CHECK-NOT: warning:
|
||||
|
@ -71,3 +73,8 @@ class A { A(int); };
|
|||
// CHECK4-NOT: Suppressed {{.*}} warnings
|
||||
// CHECK4-NOT: Use -header-filter=.* {{.*}}
|
||||
// CHECK4-QUIET-NOT: Suppressed
|
||||
|
||||
int x = 123;
|
||||
auto x_ptr = TO_FLOAT_PTR(&x);
|
||||
// CHECK5: :[[@LINE-1]]:14: warning: do not use C-style cast to convert between unrelated types
|
||||
// CHECK5-NO-SYSTEM-HEADERS-NOT: :[[@LINE-2]]:14: warning: do not use C-style cast to convert between unrelated types
|
||||
|
|
Loading…
Reference in New Issue