[clang-tools-extra] [clang-tidy] bugprone-assert-side-effect non-const operator methods (PR #71974)
via cfe-commits
cfe-commits at lists.llvm.org
Wed Nov 15 13:35:15 PST 2023
https://github.com/schenker updated https://github.com/llvm/llvm-project/pull/71974
>From 1f6e70ef97ba1bf90c829c212c6c1e09be4961f4 Mon Sep 17 00:00:00 2001
From: Thomas Schenker <thomas.schenker at protonmail.com>
Date: Fri, 10 Nov 2023 18:58:26 +0100
Subject: [PATCH 1/5] [clang-tidy] bugprone-assert-side-effect non-const
operator methods
With this PR, `bugprone-assert-side-effect` assumes that operator methods
that are not marked as `const` have side effects. This matches the
existing rule for non-operator methods.
E.g. the following snippet is now reported and was previously not:
```
std::stringstream ss;
assert(ss << 1);
```
---
.../clang-tidy/bugprone/AssertSideEffectCheck.cpp | 4 ++++
.../checkers/bugprone/assert-side-effect.cpp | 13 ++++++++++++-
2 files changed, 16 insertions(+), 1 deletion(-)
diff --git a/clang-tools-extra/clang-tidy/bugprone/AssertSideEffectCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/AssertSideEffectCheck.cpp
index 07a987359d4d8d7..599f5ac70e7a229 100644
--- a/clang-tools-extra/clang-tidy/bugprone/AssertSideEffectCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/AssertSideEffectCheck.cpp
@@ -41,6 +41,10 @@ AST_MATCHER_P2(Expr, hasSideEffect, bool, CheckFunctionCalls,
}
if (const auto *OpCallExpr = dyn_cast<CXXOperatorCallExpr>(E)) {
+ if (const auto *FuncDecl = OpCallExpr->getDirectCallee())
+ if (const auto *MethodDecl = dyn_cast<CXXMethodDecl>(FuncDecl))
+ return !MethodDecl->isConst();
+
OverloadedOperatorKind OpKind = OpCallExpr->getOperator();
return OpKind == OO_Equal || OpKind == OO_PlusEqual ||
OpKind == OO_MinusEqual || OpKind == OO_StarEqual ||
diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/assert-side-effect.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/assert-side-effect.cpp
index 6c41e1e320adeac..49d3d456deb9d35 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/bugprone/assert-side-effect.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/assert-side-effect.cpp
@@ -11,7 +11,7 @@ class MyClass {
MyClass &operator=(const MyClass &rhs) { return *this; }
- int operator-() { return 1; }
+ int operator-() const { return 1; }
operator bool() const { return true; }
@@ -84,5 +84,16 @@ int main() {
msvc_assert(mc2 = mc);
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: side effect in msvc_assert() condition discarded in release builds
+ struct {
+ int operator<<(int i) const { return i; }
+ } constOp;
+ assert(constOp << 1);
+
+ struct {
+ int operator<<(int i) { return i; }
+ } nonConstOp;
+ assert(nonConstOp << 1);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: side effect in assert() condition discarded in release builds
+
return 0;
}
>From 25dff1d9289e154fa908412584b4b04b862182ea Mon Sep 17 00:00:00 2001
From: Thomas Schenker <thomas.schenker at protonmail.com>
Date: Fri, 10 Nov 2023 21:07:39 +0100
Subject: [PATCH 2/5] use dyn_cast_or_null and add release note
---
.../clang-tidy/bugprone/AssertSideEffectCheck.cpp | 6 +++---
clang-tools-extra/docs/ReleaseNotes.rst | 4 ++++
2 files changed, 7 insertions(+), 3 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/bugprone/AssertSideEffectCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/AssertSideEffectCheck.cpp
index 599f5ac70e7a229..a6c01704b3d909f 100644
--- a/clang-tools-extra/clang-tidy/bugprone/AssertSideEffectCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/AssertSideEffectCheck.cpp
@@ -41,9 +41,9 @@ AST_MATCHER_P2(Expr, hasSideEffect, bool, CheckFunctionCalls,
}
if (const auto *OpCallExpr = dyn_cast<CXXOperatorCallExpr>(E)) {
- if (const auto *FuncDecl = OpCallExpr->getDirectCallee())
- if (const auto *MethodDecl = dyn_cast<CXXMethodDecl>(FuncDecl))
- return !MethodDecl->isConst();
+ if (const auto *MethodDecl =
+ dyn_cast_or_null<CXXMethodDecl>(OpCallExpr->getDirectCallee()))
+ return !MethodDecl->isConst();
OverloadedOperatorKind OpKind = OpCallExpr->getOperator();
return OpKind == OO_Equal || OpKind == OO_PlusEqual ||
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index 353c6fe20269274..d417036f19d565e 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -212,6 +212,10 @@ Changes in existing checks
<clang-tidy/checks/abseil/string-find-startswith>` check to also consider
``std::basic_string_view`` in addition to ``std::basic_string`` by default.
+- Improved :doc:`bugprone-assert-side-effect
+ <clang-tidy/checks/bugprone/assert-side-effect>` check to report usage of
+ non-const operator methods in assertions.
+
- Improved :doc:`bugprone-dangling-handle
<clang-tidy/checks/bugprone/dangling-handle>` check to support functional
casting during type conversions at variable initialization, now with improved
>From f8e93b572c0198f9e95e1aa90b788a0a7f828b42 Mon Sep 17 00:00:00 2001
From: Thomas Schenker <thomas.schenker at protonmail.com>
Date: Fri, 10 Nov 2023 21:45:52 +0100
Subject: [PATCH 3/5] test const overload
---
.../checkers/bugprone/assert-side-effect.cpp | 15 ++++++++-------
1 file changed, 8 insertions(+), 7 deletions(-)
diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/assert-side-effect.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/assert-side-effect.cpp
index 49d3d456deb9d35..c39cb422ebc68cc 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/bugprone/assert-side-effect.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/assert-side-effect.cpp
@@ -84,15 +84,16 @@ int main() {
msvc_assert(mc2 = mc);
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: side effect in msvc_assert() condition discarded in release builds
- struct {
+ struct ConstOverload {
int operator<<(int i) const { return i; }
- } constOp;
- assert(constOp << 1);
-
- struct {
int operator<<(int i) { return i; }
- } nonConstOp;
- assert(nonConstOp << 1);
+ };
+
+ const ConstOverload const_instance;
+ assert(const_instance << 1);
+
+ ConstOverload mutable_instance;
+ assert(mutable_instance << 1);
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: side effect in assert() condition discarded in release builds
return 0;
>From 86d89486e56868999705247cd5864c3cc729bd3e Mon Sep 17 00:00:00 2001
From: Thomas Schenker <thomas.schenker at protonmail.com>
Date: Mon, 13 Nov 2023 21:54:03 +0100
Subject: [PATCH 4/5] always consider const operator calls side-effect free,
add << and >> operators to the list of operators potentially having side
effects
---
.../bugprone/AssertSideEffectCheck.cpp | 4 +++-
clang-tools-extra/docs/ReleaseNotes.rst | 3 ++-
.../checkers/bugprone/assert-side-effect.cpp | 20 ++++++++++++++-----
3 files changed, 20 insertions(+), 7 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/bugprone/AssertSideEffectCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/AssertSideEffectCheck.cpp
index a6c01704b3d909f..43bedd4f73ef447 100644
--- a/clang-tools-extra/clang-tidy/bugprone/AssertSideEffectCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/AssertSideEffectCheck.cpp
@@ -43,7 +43,8 @@ AST_MATCHER_P2(Expr, hasSideEffect, bool, CheckFunctionCalls,
if (const auto *OpCallExpr = dyn_cast<CXXOperatorCallExpr>(E)) {
if (const auto *MethodDecl =
dyn_cast_or_null<CXXMethodDecl>(OpCallExpr->getDirectCallee()))
- return !MethodDecl->isConst();
+ if (MethodDecl->isConst())
+ return false;
OverloadedOperatorKind OpKind = OpCallExpr->getOperator();
return OpKind == OO_Equal || OpKind == OO_PlusEqual ||
@@ -51,6 +52,7 @@ AST_MATCHER_P2(Expr, hasSideEffect, bool, CheckFunctionCalls,
OpKind == OO_SlashEqual || OpKind == OO_AmpEqual ||
OpKind == OO_PipeEqual || OpKind == OO_CaretEqual ||
OpKind == OO_LessLessEqual || OpKind == OO_GreaterGreaterEqual ||
+ OpKind == OO_LessLess || OpKind == OO_GreaterGreater ||
OpKind == OO_PlusPlus || OpKind == OO_MinusMinus ||
OpKind == OO_PercentEqual || OpKind == OO_New ||
OpKind == OO_Delete || OpKind == OO_Array_New ||
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index d417036f19d565e..526fec43e98a6d4 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -214,7 +214,8 @@ Changes in existing checks
- Improved :doc:`bugprone-assert-side-effect
<clang-tidy/checks/bugprone/assert-side-effect>` check to report usage of
- non-const operator methods in assertions.
+ non-const `<<` and `>>` operators in assertions and fixed some false-positives
+ with const operators.
- Improved :doc:`bugprone-dangling-handle
<clang-tidy/checks/bugprone/dangling-handle>` check to support functional
diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/assert-side-effect.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/assert-side-effect.cpp
index c39cb422ebc68cc..c11638aa823aaeb 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/bugprone/assert-side-effect.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/assert-side-effect.cpp
@@ -11,7 +11,7 @@ class MyClass {
MyClass &operator=(const MyClass &rhs) { return *this; }
- int operator-() const { return 1; }
+ int operator-() { return 1; }
operator bool() const { return true; }
@@ -84,17 +84,27 @@ int main() {
msvc_assert(mc2 = mc);
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: side effect in msvc_assert() condition discarded in release builds
- struct ConstOverload {
+ struct OperatorTest {
int operator<<(int i) const { return i; }
int operator<<(int i) { return i; }
+ int operator+=(int i) const { return i; }
+ int operator+=(int i) { return i; }
};
- const ConstOverload const_instance;
+ const OperatorTest const_instance;
assert(const_instance << 1);
+ assert(const_instance += 1);
- ConstOverload mutable_instance;
- assert(mutable_instance << 1);
+ OperatorTest non_const_instance;
+ assert(static_cast<const OperatorTest>(non_const_instance) << 1);
+ assert(static_cast<const OperatorTest>(non_const_instance) += 1);
+ assert(non_const_instance << 1);
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: side effect in assert() condition discarded in release builds
+ assert(non_const_instance += 1);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: side effect in assert() condition discarded in release builds
+
+ assert(5<<1);
+ assert(5>>1);
return 0;
}
>From 12b5edfda8da19eec7f2427c20b7913943123b76 Mon Sep 17 00:00:00 2001
From: schenker <schenker at users.noreply.github.com>
Date: Wed, 15 Nov 2023 22:24:48 +0100
Subject: [PATCH 5/5] Update clang-tools-extra/docs/ReleaseNotes.rst
Co-authored-by: Piotr Zegar <me at piotrzegar.pl>
---
clang-tools-extra/docs/ReleaseNotes.rst | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index 526fec43e98a6d4..23111be4371e2e1 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -214,7 +214,7 @@ Changes in existing checks
- Improved :doc:`bugprone-assert-side-effect
<clang-tidy/checks/bugprone/assert-side-effect>` check to report usage of
- non-const `<<` and `>>` operators in assertions and fixed some false-positives
+ non-const ``<<`` and ``>>`` operators in assertions and fixed some false-positives
with const operators.
- Improved :doc:`bugprone-dangling-handle
More information about the cfe-commits
mailing list