-
Notifications
You must be signed in to change notification settings - Fork 15k
[clang-tidy] Ignore expresions in unevaluated context in bugprone-inc-dec-in-conditions #85849
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[clang-tidy] Ignore expresions in unevaluated context in bugprone-inc-dec-in-conditions #85849
Conversation
…-dec-in-conditions Skip checking for references to variable in unevaluated context, like decltype, static_assert and so on. Closes llvm#85838
@llvm/pr-subscribers-clang-tidy @llvm/pr-subscribers-clang-tools-extra Author: Piotr Zegar (PiotrZSL) ChangesSkip checking for references to variable in unevaluated context, like decltype, static_assert and so on. Closes #85838 Full diff: https://github.com/llvm/llvm-project/pull/85849.diff 3 Files Affected:
diff --git a/clang-tools-extra/clang-tidy/bugprone/IncDecInConditionsCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/IncDecInConditionsCheck.cpp
index 16f43128d55e87..c9990cf6d10fd5 100644
--- a/clang-tools-extra/clang-tidy/bugprone/IncDecInConditionsCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/IncDecInConditionsCheck.cpp
@@ -31,6 +31,10 @@ void IncDecInConditionsCheck::registerMatchers(MatchFinder *Finder) {
anyOf(binaryOperator(anyOf(isComparisonOperator(), isLogicalOperator())),
cxxOperatorCallExpr(isComparisonOperator())));
+ auto IsInUnevaluatedContext =
+ expr(anyOf(hasAncestor(expr(matchers::hasUnevaluatedContext())),
+ hasAncestor(typeLoc())));
+
Finder->addMatcher(
expr(
OperatorMatcher, unless(isExpansionInSystemHeader()),
@@ -47,7 +51,8 @@ void IncDecInConditionsCheck::registerMatchers(MatchFinder *Finder) {
hasDescendant(
expr(unless(equalsBoundNode("operand")),
matchers::isStatementIdenticalToBoundNode(
- "operand"))
+ "operand"),
+ unless(IsInUnevaluatedContext))
.bind("second")))))
.bind("operator"))),
this);
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index 44680f79de6f54..8803be56d4fd1a 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -132,6 +132,10 @@ Changes in existing checks
<clang-tidy/checks/bugprone/assert-side-effect>` check by detecting side
effect from calling a method with non-const reference parameters.
+- Improved :doc:`bugprone-inc-dec-in-conditions
+ <clang-tidy/checks/bugprone/inc-dec-in-conditions>` check to ignore code
+ within unevaluated contexts, such as ``decltype``.
+
- Improved :doc:`bugprone-non-zero-enum-to-bool-conversion
<clang-tidy/checks/bugprone/non-zero-enum-to-bool-conversion>` check by
eliminating false positives resulting from direct usage of bitwise operators
diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/inc-dec-in-conditions.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/inc-dec-in-conditions.cpp
index 82af039973c3bb..a9cb27a47f35b5 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/bugprone/inc-dec-in-conditions.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/inc-dec-in-conditions.cpp
@@ -68,3 +68,12 @@ bool doubleCheck(Container<int> x) {
// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: decrementing and referencing a variable in a complex condition can cause unintended side-effects due to C++'s order of evaluation, consider moving the modification outside of the condition to avoid misunderstandings [bugprone-inc-dec-in-conditions]
// CHECK-MESSAGES: :[[@LINE-2]]:31: warning: incrementing and referencing a variable in a complex condition can cause unintended side-effects due to C++'s order of evaluation, consider moving the modification outside of the condition to avoid misunderstandings [bugprone-inc-dec-in-conditions]
}
+
+namespace PR85838 {
+ void test()
+ {
+ auto foo = 0;
+ auto bar = 0;
+ if (++foo < static_cast<decltype(foo)>(bar)) {}
+ }
+}
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good, but the operand
node may also be in an unevaluated context, you only guard against the non ++/--
expr being in an unevaluated context here.
Fix: add unless(IsInUnevaluatedContext)
to both expr().bind("operand")
.
Example: if (foo < static_cast<decltype(foo++)>(bar)) {}
✅ With the latest revision this PR passed the Python code formatter. |
✅ With the latest revision this PR passed the C/C++ code formatter. |
Skip checking for references to variable in unevaluated context, like decltype, static_assert and so on.
Closes #85838