Author: mitchell Date: 2025-12-14T12:31:25+08:00 New Revision: 72574b81956ad8bab51deaae0adab5ff6be40a30
URL: https://github.com/llvm/llvm-project/commit/72574b81956ad8bab51deaae0adab5ff6be40a30 DIFF: https://github.com/llvm/llvm-project/commit/72574b81956ad8bab51deaae0adab5ff6be40a30.diff LOG: [clang-tidy] Add `IgnoreMacro` option to `bugprone-chained-comparison` (#171975) Closes #171130 --------- Co-authored-by: Baranov Victor <[email protected]> Added: clang-tools-extra/test/clang-tidy/checkers/bugprone/chained-comparison-ignore-macros.cpp Modified: clang-tools-extra/clang-tidy/bugprone/ChainedComparisonCheck.cpp clang-tools-extra/clang-tidy/bugprone/ChainedComparisonCheck.h clang-tools-extra/docs/ReleaseNotes.rst clang-tools-extra/docs/clang-tidy/checks/bugprone/chained-comparison.rst clang-tools-extra/test/clang-tidy/checkers/bugprone/chained-comparison.cpp Removed: ################################################################################ diff --git a/clang-tools-extra/clang-tidy/bugprone/ChainedComparisonCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/ChainedComparisonCheck.cpp index 47acc217b2c24..8b1c8aaa48e3e 100644 --- a/clang-tools-extra/clang-tidy/bugprone/ChainedComparisonCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/ChainedComparisonCheck.cpp @@ -112,6 +112,15 @@ void ChainedComparisonData::extract(const Expr *Op) { } } +ChainedComparisonCheck::ChainedComparisonCheck(StringRef Name, + ClangTidyContext *Context) + : ClangTidyCheck(Name, Context), + IgnoreMacros(Options.get("IgnoreMacros", false)) {} + +void ChainedComparisonCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { + Options.store(Opts, "IgnoreMacros", IgnoreMacros); +} + void ChainedComparisonCheck::registerMatchers(MatchFinder *Finder) { const auto OperatorMatcher = expr(anyOf( binaryOperator(isComparisonOperator(), @@ -128,6 +137,9 @@ void ChainedComparisonCheck::registerMatchers(MatchFinder *Finder) { void ChainedComparisonCheck::check(const MatchFinder::MatchResult &Result) { const auto *MatchedOperator = Result.Nodes.getNodeAs<Expr>("op"); + if (IgnoreMacros && MatchedOperator->getBeginLoc().isMacroID()) + return; + ChainedComparisonData Data(MatchedOperator); if (Data.Operands.empty()) return; diff --git a/clang-tools-extra/clang-tidy/bugprone/ChainedComparisonCheck.h b/clang-tools-extra/clang-tidy/bugprone/ChainedComparisonCheck.h index 7c1022904a3a6..dacfc68a8a42a 100644 --- a/clang-tools-extra/clang-tidy/bugprone/ChainedComparisonCheck.h +++ b/clang-tools-extra/clang-tidy/bugprone/ChainedComparisonCheck.h @@ -20,13 +20,16 @@ namespace clang::tidy::bugprone { /// https://clang.llvm.org/extra/clang-tidy/checks/bugprone/chained-comparison.html class ChainedComparisonCheck : public ClangTidyCheck { public: - ChainedComparisonCheck(StringRef Name, ClangTidyContext *Context) - : ClangTidyCheck(Name, Context) {} + ChainedComparisonCheck(StringRef Name, ClangTidyContext *Context); void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; + void storeOptions(ClangTidyOptions::OptionMap &Opts) override; std::optional<TraversalKind> getCheckTraversalKind() const override { return TK_IgnoreUnlessSpelledInSource; } + +private: + const bool IgnoreMacros; }; } // namespace clang::tidy::bugprone diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index 27467d082ea1e..afd873e4007ac 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -344,6 +344,11 @@ New check aliases Changes in existing checks ^^^^^^^^^^^^^^^^^^^^^^^^^^ +- Improved :doc:`bugprone-chained-comparison + <clang-tidy/checks/bugprone/chained-comparison>` check by adding a + new option `IgnoreMacros` to suppress warnings within macro + expansions. + - Improved :doc:`bugprone-easily-swappable-parameters <clang-tidy/checks/bugprone/easily-swappable-parameters>` check by correcting a spelling mistake on its option diff --git a/clang-tools-extra/docs/clang-tidy/checks/bugprone/chained-comparison.rst b/clang-tools-extra/docs/clang-tidy/checks/bugprone/chained-comparison.rst index 45b069a8e29de..d3ad0dfe5adda 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/bugprone/chained-comparison.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/bugprone/chained-comparison.rst @@ -71,3 +71,11 @@ developer's intention more explicit and help avoid misunderstanding. // This block will be executed } +Options +------- + +.. option:: IgnoreMacros + + If `true`, the check will not warn on chained comparisons inside macros. + Default is `false`. + diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/chained-comparison-ignore-macros.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/chained-comparison-ignore-macros.cpp new file mode 100644 index 0000000000000..7141abd619974 --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/chained-comparison-ignore-macros.cpp @@ -0,0 +1,37 @@ +// RUN: %check_clang_tidy -std=c++98-or-later --extra-arg=-Wno-error=parentheses %s bugprone-chained-comparison %t -- -config="{CheckOptions: {bugprone-chained-comparison.IgnoreMacros: true}}" + +#define CHAINED_COMPARE(a, b, c) (a < b < c) + +void macro_test(int x, int y, int z) { + bool result = CHAINED_COMPARE(x, y, z); +} + +#define NESTED_LESS(a, b) a < b +#define NESTED_CHAIN(a, b, c) NESTED_LESS(a, b) < c + +void nested_macro_test(int x, int y, int z) { + bool result = NESTED_CHAIN(x, y, z); +} + +#define LESS_OP < + +void operator_macro_test(int x, int y, int z) { + bool result = x LESS_OP y LESS_OP z; +} +// CHECK-MESSAGES: :[[@LINE-2]]:19: warning: chained comparison 'v0 < v1 < v2' may generate unintended results + +#define PARTIAL_LESS(a, b) a < b + +void mixed_macro_test(int x, int y, int z) { + bool result = PARTIAL_LESS(x, y) < z; +} + +void if_macro_test(int x, int y, int z) { + if (CHAINED_COMPARE(x, y, z)) {} +} + +#define LONG_CHAIN_MACRO(v) v[0] < v[1] < v[2] < v[3] + +void long_chain_macro_test(int v[4]) { + bool result = LONG_CHAIN_MACRO(v); +} diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/chained-comparison.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/chained-comparison.cpp index 88813f72e37ca..2c32d58c23a31 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/bugprone/chained-comparison.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/chained-comparison.cpp @@ -89,3 +89,44 @@ bool mixedBinaryAndCpp(Value a, Value b, bool c) { return a < b == c; } // CHECK-MESSAGES: :[[@LINE-2]]:12: warning: chained comparison 'v0 < v1 == v2' may generate unintended results, use parentheses to specify order of evaluation or a logical operator to separate comparison expressions [bugprone-chained-comparison] + +#define CHAINED_COMPARE(a, b, c) (a < b < c) + +void macro_test(int x, int y, int z) { + bool result = CHAINED_COMPARE(x, y, z); +} +// CHECK-MESSAGES: :[[@LINE-2]]:35: warning: chained comparison 'v0 < v1 < v2' may generate unintended results, use parentheses to specify order of evaluation or a logical operator to separate comparison expressions [bugprone-chained-comparison] + +#define NESTED_LESS(a, b) a < b +#define NESTED_CHAIN(a, b, c) NESTED_LESS(a, b) < c + +void nested_macro_test(int x, int y, int z) { + bool result = NESTED_CHAIN(x, y, z); +} +// CHECK-MESSAGES: :[[@LINE-2]]:32: warning: chained comparison 'v0 < v1 < v2' may generate unintended results, use parentheses to specify order of evaluation or a logical operator to separate comparison expressions [bugprone-chained-comparison] + +#define LESS_OP < + +void operator_macro_test(int x, int y, int z) { + bool result = x LESS_OP y LESS_OP z; +} +// CHECK-MESSAGES: :[[@LINE-2]]:19: warning: chained comparison 'v0 < v1 < v2' may generate unintended results, use parentheses to specify order of evaluation or a logical operator to separate comparison expressions [bugprone-chained-comparison] + +#define PARTIAL_LESS(a, b) a < b + +void mixed_macro_test(int x, int y, int z) { + bool result = PARTIAL_LESS(x, y) < z; +} +// CHECK-MESSAGES: :[[@LINE-2]]:32: warning: chained comparison 'v0 < v1 < v2' may generate unintended results, use parentheses to specify order of evaluation or a logical operator to separate comparison expressions [bugprone-chained-comparison] + +void if_macro_test(int x, int y, int z) { + if (CHAINED_COMPARE(x, y, z)) {} +} +// CHECK-MESSAGES: :[[@LINE-2]]:25: warning: chained comparison 'v0 < v1 < v2' may generate unintended results, use parentheses to specify order of evaluation or a logical operator to separate comparison expressions [bugprone-chained-comparison] + +#define LONG_CHAIN_MACRO(v) v[0] < v[1] < v[2] < v[3] + +void long_chain_macro_test(int v[4]) { + bool result = LONG_CHAIN_MACRO(v); +} +// CHECK-MESSAGES: :[[@LINE-2]]:36: warning: chained comparison 'v0 < v1 < v2 < v3' may generate unintended results, use parentheses to specify order of evaluation or a logical operator to separate comparison expressions [bugprone-chained-comparison] _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
