[clang-tools-extra] Add AllowFalseEvaluated flag to clang-tidy noexcept-move-constructor check (PR #126897)
Dmitry Nechitaev via cfe-commits
cfe-commits at lists.llvm.org
Wed Feb 12 09:09:09 PST 2025
https://github.com/Nechda updated https://github.com/llvm/llvm-project/pull/126897
>From 8baebe758b4f07933294b88bf2390fbb14ddeed0 Mon Sep 17 00:00:00 2001
From: Dmitry Nechitaev <nechda at yandex-team.ru>
Date: Wed, 12 Feb 2025 14:30:47 +0300
Subject: [PATCH 1/4] Add AllowFalseEvaluated to clang-tidy
noexcept-move-constructor check
---
.../performance/NoexceptFunctionBaseCheck.cpp | 2 +-
.../performance/NoexceptFunctionBaseCheck.h | 8 ++-
...move-constructor-allow-false-evaluated.cpp | 63 +++++++++++++++++++
3 files changed, 71 insertions(+), 2 deletions(-)
create mode 100644 clang-tools-extra/test/clang-tidy/checkers/performance/noexcept-move-constructor-allow-false-evaluated.cpp
diff --git a/clang-tools-extra/clang-tidy/performance/NoexceptFunctionBaseCheck.cpp b/clang-tools-extra/clang-tidy/performance/NoexceptFunctionBaseCheck.cpp
index 911cd1b533367..8371b6aafd8ba 100644
--- a/clang-tools-extra/clang-tidy/performance/NoexceptFunctionBaseCheck.cpp
+++ b/clang-tools-extra/clang-tidy/performance/NoexceptFunctionBaseCheck.cpp
@@ -30,7 +30,7 @@ void NoexceptFunctionBaseCheck::check(const MatchFinder::MatchResult &Result) {
const Expr *NoexceptExpr = ProtoType->getNoexceptExpr();
if (NoexceptExpr) {
NoexceptExpr = NoexceptExpr->IgnoreImplicit();
- if (!isa<CXXBoolLiteralExpr>(NoexceptExpr))
+ if (!isa<CXXBoolLiteralExpr>(NoexceptExpr) && !AllowFalseEvaluated)
reportNoexceptEvaluatedToFalse(FuncDecl, NoexceptExpr);
return;
}
diff --git a/clang-tools-extra/clang-tidy/performance/NoexceptFunctionBaseCheck.h b/clang-tools-extra/clang-tidy/performance/NoexceptFunctionBaseCheck.h
index 4775219d7e439..cd1da1fbeca55 100644
--- a/clang-tools-extra/clang-tidy/performance/NoexceptFunctionBaseCheck.h
+++ b/clang-tools-extra/clang-tidy/performance/NoexceptFunctionBaseCheck.h
@@ -22,7 +22,8 @@ namespace clang::tidy::performance {
class NoexceptFunctionBaseCheck : public ClangTidyCheck {
public:
NoexceptFunctionBaseCheck(StringRef Name, ClangTidyContext *Context)
- : ClangTidyCheck(Name, Context) {}
+ : ClangTidyCheck(Name, Context)
+ , AllowFalseEvaluated(Options.getLocalOrGlobal("AllowFalseEvaluated", false)) {}
bool isLanguageVersionSupported(const LangOptions &LangOpts) const override {
return LangOpts.CPlusPlus11 && LangOpts.CXXExceptions;
@@ -33,6 +34,10 @@ class NoexceptFunctionBaseCheck : public ClangTidyCheck {
return TK_IgnoreUnlessSpelledInSource;
}
+ void storeOptions(ClangTidyOptions::OptionMap &Opts) override {
+ Options.store(Opts, "AllowFalseEvaluated", AllowFalseEvaluated);
+ }
+
protected:
virtual DiagnosticBuilder
reportMissingNoexcept(const FunctionDecl *FuncDecl) = 0;
@@ -42,6 +47,7 @@ class NoexceptFunctionBaseCheck : public ClangTidyCheck {
static constexpr StringRef BindFuncDeclName = "FuncDecl";
private:
+ bool AllowFalseEvaluated;
utils::ExceptionSpecAnalyzer SpecAnalyzer;
};
diff --git a/clang-tools-extra/test/clang-tidy/checkers/performance/noexcept-move-constructor-allow-false-evaluated.cpp b/clang-tools-extra/test/clang-tidy/checkers/performance/noexcept-move-constructor-allow-false-evaluated.cpp
new file mode 100644
index 0000000000000..3552eaa7c50ea
--- /dev/null
+++ b/clang-tools-extra/test/clang-tidy/checkers/performance/noexcept-move-constructor-allow-false-evaluated.cpp
@@ -0,0 +1,63 @@
+// RUN: %check_clang_tidy %s performance-noexcept-move-constructor %t -- -- -fexceptions
+
+// RUN: %check_clang_tidy -check-suffix=CONFIG %s performance-noexcept-move-constructor,performance-noexcept-destructor %t -- \
+// RUN: -config="{CheckOptions: {performance-noexcept-move-constructor.AllowFalseEvaluated: true}}" \
+// RUN: -- -fexceptions
+
+namespace std
+{
+ template <typename T>
+ struct is_nothrow_move_constructible
+ {
+ static constexpr bool value = __is_nothrow_constructible(T, __add_rvalue_reference(T));
+ };
+} // namespace std
+
+struct ThrowOnAnything {
+ ThrowOnAnything() noexcept(false);
+ ThrowOnAnything(ThrowOnAnything&&) noexcept(false);
+ // CHECK-MESSAGES-NOT: :[[@LINE-1]]:3: warning: move constructors should be marked noexcept
+ // CHECK-MESSAGES-CONFIG-NOT: :[[@LINE-2]]:3: warning: move constructors should be marked noexcept
+ ThrowOnAnything& operator=(ThrowOnAnything &&) noexcept(false);
+ ~ThrowOnAnything() noexcept(false);
+};
+
+struct C_1 {
+ static constexpr bool kFalse = false;
+ C_1(C_1&&) noexcept(kFalse) = default;
+ // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: noexcept specifier on the move constructor evaluates to 'false' [performance-noexcept-move-constructor]
+ // CHECK-MESSAGES-CONFIG-NOT: :[[@LINE-2]]:25: warning: noexcept specifier on the move constructor evaluates to 'false' [performance-noexcept-move-constructor]
+
+ C_1 &operator=(C_1 &&) noexcept(kFalse);
+ // CHECK-MESSAGES: :[[@LINE-1]]:37: warning: noexcept specifier on the move assignment operator evaluates to 'false' [performance-noexcept-move-constructor]
+ // CHECK-MESSAGES-CONFIG-NOT: :[[@LINE-2]]:37: warning: noexcept specifier on the move assignment operator evaluates to 'false' [performance-noexcept-move-constructor]
+};
+
+struct C_2 {
+ static constexpr bool kEval = std::is_nothrow_move_constructible<ThrowOnAnything>::value;
+ static_assert(!kEval); // kEval == false;
+
+ C_2(C_2&&) noexcept(kEval) = default;
+ // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: noexcept specifier on the move constructor evaluates to 'false' [performance-noexcept-move-constructor]
+ // CHECK-MESSAGES-CONFIG-NOT: :[[@LINE-2]]:25: warning: noexcept specifier on the move constructor evaluates to 'false' [performance-noexcept-move-constructor]
+
+ C_2 &operator=(C_2 &&) noexcept(kEval);
+ // CHECK-MESSAGES: :[[@LINE-1]]:37: warning: noexcept specifier on the move assignment operator evaluates to 'false' [performance-noexcept-move-constructor]
+ // CHECK-MESSAGES-CONFIG-NOT: :[[@LINE-2]]:37: warning: noexcept specifier on the move assignment operator evaluates to 'false' [performance-noexcept-move-constructor]
+
+ ThrowOnAnything field;
+};
+
+struct C_3 {
+ static constexpr bool kEval = std::is_nothrow_move_constructible<ThrowOnAnything>::value;
+ static_assert(!kEval); // kEval == false;
+
+ C_3(C_3&&) noexcept(kEval) = default;
+ // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: noexcept specifier on the move constructor evaluates to 'false' [performance-noexcept-move-constructor]
+ // CHECK-MESSAGES-CONFIG-NOT: :[[@LINE-2]]:25: warning: noexcept specifier on the move constructor evaluates to 'false' [performance-noexcept-move-constructor]
+
+ ~C_3() noexcept(kEval) = default;
+ // CHECK-MESSAGES-CONFIG: :[[@LINE-1]]:21: warning: noexcept specifier on the destructor evaluates to 'false'
+
+ ThrowOnAnything field;
+};
>From 25a859cfe936df026389f9bd3a63243aa86c3ba2 Mon Sep 17 00:00:00 2001
From: Dmitry Nechitaev <nechda at yandex-team.ru>
Date: Wed, 12 Feb 2025 19:51:47 +0300
Subject: [PATCH 2/4] Update docs
---
clang-tools-extra/docs/ReleaseNotes.rst | 5 +++++
.../checks/performance/noexcept-move-constructor.rst | 12 ++++++++++++
2 files changed, 17 insertions(+)
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index 6b8fe22242417..4cd6ddc7a9337 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -106,6 +106,11 @@ Changes in existing checks
<clang-tidy/checks/bugprone/unsafe-functions>` check to allow specifying
additional C++ member functions to match.
+- Improved :doc:`performance-noexcept-move-constructor
+ <clang-tidy/checks/performance/noexcept-move-constructor>`. Check allows
+ move-constructors with `noexcept(expr)`, even if `expr` evaluates to `false`,
+ if the `AllowFalseEvaluated` flag is specified.
+
- Improved :doc:`misc-redundant-expression
<clang-tidy/checks/misc/redundant-expression>` check by providing additional
examples and fixing some macro related false positives.
diff --git a/clang-tools-extra/docs/clang-tidy/checks/performance/noexcept-move-constructor.rst b/clang-tools-extra/docs/clang-tidy/checks/performance/noexcept-move-constructor.rst
index 05f1d85f1af5a..493b6da9a1bd1 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/performance/noexcept-move-constructor.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/performance/noexcept-move-constructor.rst
@@ -11,3 +11,15 @@ evaluates to ``false`` (but is not a ``false`` literal itself).
Move constructors of all the types used with STL containers, for example,
need to be declared ``noexcept``. Otherwise STL will choose copy constructors
instead. The same is valid for move assignment operations.
+
+Options
+-------
+
+The following options are described below:
+
+ - :option:`AllowFalseEvaluated`
+
+.. option:: AllowFalseEvaluated
+
+ When defined, the check will not generate any warning
+ if the `expr` in `noexcept(expr)` evaluates to `false`.
>From 3d7fe5f16efb191de1d8b133911826a9faf955fa Mon Sep 17 00:00:00 2001
From: Dmitry Nechitaev <nechda at yandex-team.ru>
Date: Wed, 12 Feb 2025 20:02:04 +0300
Subject: [PATCH 3/4] Fix syntax in doc
---
clang-tools-extra/docs/ReleaseNotes.rst | 10 +++++-----
.../checks/performance/noexcept-move-constructor.rst | 3 ++-
2 files changed, 7 insertions(+), 6 deletions(-)
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index 4cd6ddc7a9337..b9593ff97ce37 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -106,15 +106,15 @@ Changes in existing checks
<clang-tidy/checks/bugprone/unsafe-functions>` check to allow specifying
additional C++ member functions to match.
-- Improved :doc:`performance-noexcept-move-constructor
- <clang-tidy/checks/performance/noexcept-move-constructor>`. Check allows
- move-constructors with `noexcept(expr)`, even if `expr` evaluates to `false`,
- if the `AllowFalseEvaluated` flag is specified.
-
- Improved :doc:`misc-redundant-expression
<clang-tidy/checks/misc/redundant-expression>` check by providing additional
examples and fixing some macro related false positives.
+- Improved :doc:`performance-noexcept-move-constructor
+ <clang-tidy/checks/performance/noexcept-move-constructor>`. Check allows
+ move-constructors with ``noexcept(expr)``, even if ``expr`` evaluates to ``false``,
+ if the ``AllowFalseEvaluated`` flag is specified.
+
Removed checks
^^^^^^^^^^^^^^
diff --git a/clang-tools-extra/docs/clang-tidy/checks/performance/noexcept-move-constructor.rst b/clang-tools-extra/docs/clang-tidy/checks/performance/noexcept-move-constructor.rst
index 493b6da9a1bd1..e28845d095262 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/performance/noexcept-move-constructor.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/performance/noexcept-move-constructor.rst
@@ -22,4 +22,5 @@ The following options are described below:
.. option:: AllowFalseEvaluated
When defined, the check will not generate any warning
- if the `expr` in `noexcept(expr)` evaluates to `false`.
+ if the ``expr`` in ``noexcept(expr)`` evaluates to ``false``.
+ The default value is ``false``.
>From cde2c33d789efc6667409abf93a54af03a4eb22c Mon Sep 17 00:00:00 2001
From: Dmitry Nechitaev <nechda at yandex-team.ru>
Date: Wed, 12 Feb 2025 20:08:43 +0300
Subject: [PATCH 4/4] Doc syntax for options & values
---
clang-tools-extra/docs/ReleaseNotes.rst | 2 +-
.../clang-tidy/checks/performance/noexcept-move-constructor.rst | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index b9593ff97ce37..3bdf206d8ce39 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -113,7 +113,7 @@ Changes in existing checks
- Improved :doc:`performance-noexcept-move-constructor
<clang-tidy/checks/performance/noexcept-move-constructor>`. Check allows
move-constructors with ``noexcept(expr)``, even if ``expr`` evaluates to ``false``,
- if the ``AllowFalseEvaluated`` flag is specified.
+ if the `AllowFalseEvaluated` flag is specified.
Removed checks
^^^^^^^^^^^^^^
diff --git a/clang-tools-extra/docs/clang-tidy/checks/performance/noexcept-move-constructor.rst b/clang-tools-extra/docs/clang-tidy/checks/performance/noexcept-move-constructor.rst
index e28845d095262..07fc23937870d 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/performance/noexcept-move-constructor.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/performance/noexcept-move-constructor.rst
@@ -23,4 +23,4 @@ The following options are described below:
When defined, the check will not generate any warning
if the ``expr`` in ``noexcept(expr)`` evaluates to ``false``.
- The default value is ``false``.
+ The default value is `false`.
More information about the cfe-commits
mailing list