[clang] [clang-tools-extra] [clang-tidy] fix match for binaryOperator in ExprMutationAnalyzer for misc-const-correctness (PR #70559)
Julian Schmidt via cfe-commits
cfe-commits at lists.llvm.org
Mon Nov 13 12:27:01 PST 2023
https://github.com/5chmidti updated https://github.com/llvm/llvm-project/pull/70559
>From b29eb35fe8597ceefc4c615817174181a16f3c4c Mon Sep 17 00:00:00 2001
From: Julian Schmidt <44101708+5chmidti at users.noreply.github.com>
Date: Sat, 28 Oct 2023 18:08:51 +0200
Subject: [PATCH 1/6] [clang-tidy] fix match for binaryOperator in
ExprMutationAnalyzer for misc-const-correctness
The `ExprMutationAnalyzer`s matcher of `binaryOperator`s
that contained the variable expr, were previously narrowing the
variable to be type dependent, when the `binaryOperator` should
have been narrowed as dependent.
The variable we are trying to find mutations for does
not need to be the dependent type, the other operand of
the `binaryOperator` could be dependent.
Fixes #57297
---
clang-tools-extra/docs/ReleaseNotes.rst | 5 +++++
.../checkers/misc/const-correctness-templates.cpp | 11 +++++++++++
clang/docs/ReleaseNotes.rst | 3 +++
clang/lib/Analysis/ExprMutationAnalyzer.cpp | 6 +++---
clang/unittests/Analysis/ExprMutationAnalyzerTest.cpp | 11 +++++++++++
5 files changed, 33 insertions(+), 3 deletions(-)
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index 5ce38ab48bf295f..bb75c9a3ce08125 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -308,6 +308,11 @@ Changes in existing checks
<clang-tidy/checks/misc/const-correctness>` check to avoid false positive when
using pointer to member function.
+- Improved :doc:`misc-const-correctness
+ <clang-tidy/checks/misc/const-correctness>` check to not warn on uses in
+ type-dependent binary operators, when the variable that is being
+ looked at, is not the dependent operand.
+
- Improved :doc:`misc-include-cleaner
<clang-tidy/checks/misc/include-cleaner>` check by adding option
`DeduplicateFindings` to output one finding per symbol occurrence, avoid
diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-templates.cpp b/clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-templates.cpp
index 7b5ccabdd6ef611..415bb06020b9dc3 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-templates.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-templates.cpp
@@ -20,3 +20,14 @@ void instantiate_template_cases() {
type_dependent_variables<int>();
type_dependent_variables<float>();
}
+
+namespace gh57297{
+struct Stream {};
+// Explicitly not declaring a (templated) stream operator
+// so the `<<` is a `binaryOperator` with a dependent type.
+template <typename T> void f() {
+ T t;
+ Stream stream;
+ stream << t;
+}
+} // namespace gh57297
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 2595737e8b3b143..fb9afc0646ac8cb 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -683,6 +683,9 @@ Bug Fixes to AST Handling
- Fixed a bug where RecursiveASTVisitor fails to visit the
initializer of a bitfield.
`Issue 64916 <https://github.com/llvm/llvm-project/issues/64916>`_
+- Fixed a bug where ``ExprMutationAnalyzer`` did not find a potential mutation
+ for uses in type-dependent binary operators, when the variable that is being
+ looked at, is not the dependent operand.
Miscellaneous Bug Fixes
^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang/lib/Analysis/ExprMutationAnalyzer.cpp b/clang/lib/Analysis/ExprMutationAnalyzer.cpp
index f2e1beb025423cf..624a643cc60e4ba 100644
--- a/clang/lib/Analysis/ExprMutationAnalyzer.cpp
+++ b/clang/lib/Analysis/ExprMutationAnalyzer.cpp
@@ -296,9 +296,9 @@ const Stmt *ExprMutationAnalyzer::findDirectMutation(const Expr *Exp) {
// resolved and modelled as `binaryOperator` on a dependent type.
// Such instances are considered a modification, because they can modify
// in different instantiations of the template.
- binaryOperator(hasEitherOperand(
- allOf(ignoringImpCasts(canResolveToExpr(equalsNode(Exp))),
- isTypeDependent()))),
+ binaryOperator(
+ hasEitherOperand(ignoringImpCasts(canResolveToExpr(equalsNode(Exp)))),
+ isTypeDependent()),
// Within class templates and member functions the member expression might
// not be resolved. In that case, the `callExpr` is considered to be a
// modification.
diff --git a/clang/unittests/Analysis/ExprMutationAnalyzerTest.cpp b/clang/unittests/Analysis/ExprMutationAnalyzerTest.cpp
index c0a398394093c48..cfa3c535ce35292 100644
--- a/clang/unittests/Analysis/ExprMutationAnalyzerTest.cpp
+++ b/clang/unittests/Analysis/ExprMutationAnalyzerTest.cpp
@@ -343,6 +343,17 @@ TEST(ExprMutationAnalyzerTest, UnresolvedOperator) {
EXPECT_TRUE(isMutated(Results, AST.get()));
}
+TEST(ExprMutationAnalyzerTest, DependentOperatorWithNonDependentOperand) {
+ // gh57297
+ // Explicitly not declaring a (templated) stream operator
+ // so the `<<` is a `binaryOperator` with a dependent type.
+ const auto AST = buildASTFromCode("struct Stream {}; template <typename T> "
+ "void f() { T t; Stream x; x << t;}");
+ const auto Results =
+ match(withEnclosingCompound(declRefTo("x")), AST->getASTContext());
+ EXPECT_THAT(mutatedBy(Results, AST.get()), ElementsAre("x << t"));
+}
+
// Section: expression as call argument
TEST(ExprMutationAnalyzerTest, ByValueArgument) {
>From 3909609b88e1643aa13f21613123f693bae52ba1 Mon Sep 17 00:00:00 2001
From: Julian Schmidt <44101708+5chmidti at users.noreply.github.com>
Date: Sat, 28 Oct 2023 19:57:51 +0200
Subject: [PATCH 2/6] rm release note comment from clang specific docs
---
clang/docs/ReleaseNotes.rst | 3 ---
1 file changed, 3 deletions(-)
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index fb9afc0646ac8cb..2595737e8b3b143 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -683,9 +683,6 @@ Bug Fixes to AST Handling
- Fixed a bug where RecursiveASTVisitor fails to visit the
initializer of a bitfield.
`Issue 64916 <https://github.com/llvm/llvm-project/issues/64916>`_
-- Fixed a bug where ``ExprMutationAnalyzer`` did not find a potential mutation
- for uses in type-dependent binary operators, when the variable that is being
- looked at, is not the dependent operand.
Miscellaneous Bug Fixes
^^^^^^^^^^^^^^^^^^^^^^^
>From 196eb2ac73126db4272a632d3391f0dd17703107 Mon Sep 17 00:00:00 2001
From: Julian Schmidt <44101708+5chmidti at users.noreply.github.com>
Date: Wed, 8 Nov 2023 19:33:14 +0100
Subject: [PATCH 3/6] fix windows CI failure
- explicitly instantiate template
- provide operator int() to Stream to ensure << is a BinaryOperator,
not a CXXOperatorCallExpr
---
.../misc/const-correctness-templates.cpp | 19 +++++++++++--------
.../Analysis/ExprMutationAnalyzerTest.cpp | 16 ++++++++++++----
2 files changed, 23 insertions(+), 12 deletions(-)
diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-templates.cpp b/clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-templates.cpp
index 415bb06020b9dc3..98063bcf47af8f1 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-templates.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-templates.cpp
@@ -22,12 +22,15 @@ void instantiate_template_cases() {
}
namespace gh57297{
-struct Stream {};
-// Explicitly not declaring a (templated) stream operator
-// so the `<<` is a `binaryOperator` with a dependent type.
-template <typename T> void f() {
- T t;
- Stream stream;
- stream << t;
-}
+// The expression to check may not be the dependent operand in a dependent
+// operator.
+
+// Explicitly adding the conversion operator to int for `Stream` to make the
+// explicit instantiation (required due to windows' delayed template parsing
+// pre C++20) of `f` work without compile errors. Writing an `operator<<` for
+// `Stream` would make the `x << t` expression a CXXOperatorCallExpr, not a
+// BinaryOperator.
+struct Stream { operator int(); };
+template <typename T> void f() { T t; Stream x; x << t; }
+void foo() { f<int>(); }
} // namespace gh57297
diff --git a/clang/unittests/Analysis/ExprMutationAnalyzerTest.cpp b/clang/unittests/Analysis/ExprMutationAnalyzerTest.cpp
index cfa3c535ce35292..6d8582b48ee0a02 100644
--- a/clang/unittests/Analysis/ExprMutationAnalyzerTest.cpp
+++ b/clang/unittests/Analysis/ExprMutationAnalyzerTest.cpp
@@ -345,10 +345,18 @@ TEST(ExprMutationAnalyzerTest, UnresolvedOperator) {
TEST(ExprMutationAnalyzerTest, DependentOperatorWithNonDependentOperand) {
// gh57297
- // Explicitly not declaring a (templated) stream operator
- // so the `<<` is a `binaryOperator` with a dependent type.
- const auto AST = buildASTFromCode("struct Stream {}; template <typename T> "
- "void f() { T t; Stream x; x << t;}");
+ // The expression to check may not be the dependent operand in a dependent
+ // operator.
+
+ // Explicitly adding the conversion operator to int for `Stream` to make the
+ // explicit instantiation (required due to windows' delayed template parsing
+ // pre C++20) of `f` work without compile errors. Writing an `operator<<` for
+ // `Stream` would make the `x << t` expression a CXXOperatorCallExpr, not a
+ // BinaryOperator.
+ const auto AST = buildASTFromCode(
+ "struct Stream { operator int(); };"
+ "template <typename T> void f() { T t; Stream x; x << t; }"
+ "void foo() { f<int>(); }");
const auto Results =
match(withEnclosingCompound(declRefTo("x")), AST->getASTContext());
EXPECT_THAT(mutatedBy(Results, AST.get()), ElementsAre("x << t"));
>From 1b6dead9af110a4013b74d54749c55c5005ffe04 Mon Sep 17 00:00:00 2001
From: Julian Schmidt <44101708+5chmidti at users.noreply.github.com>
Date: Sun, 12 Nov 2023 23:06:50 +0100
Subject: [PATCH 4/6] test with `-fno-delayed-template-parsing` instead
---
.../checkers/misc/const-correctness-templates.cpp | 10 +++-------
.../Analysis/ExprMutationAnalyzerTest.cpp | 15 ++++++---------
2 files changed, 9 insertions(+), 16 deletions(-)
diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-templates.cpp b/clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-templates.cpp
index 98063bcf47af8f1..794578ceeeba8fc 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-templates.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-templates.cpp
@@ -25,12 +25,8 @@ namespace gh57297{
// The expression to check may not be the dependent operand in a dependent
// operator.
-// Explicitly adding the conversion operator to int for `Stream` to make the
-// explicit instantiation (required due to windows' delayed template parsing
-// pre C++20) of `f` work without compile errors. Writing an `operator<<` for
-// `Stream` would make the `x << t` expression a CXXOperatorCallExpr, not a
-// BinaryOperator.
-struct Stream { operator int(); };
+// Explicitly not declaring a (templated) stream operator
+// so the `<<` is a `binaryOperator` with a dependent type.
+struct Stream { };
template <typename T> void f() { T t; Stream x; x << t; }
-void foo() { f<int>(); }
} // namespace gh57297
diff --git a/clang/unittests/Analysis/ExprMutationAnalyzerTest.cpp b/clang/unittests/Analysis/ExprMutationAnalyzerTest.cpp
index 6d8582b48ee0a02..f1a1f857a0ee5be 100644
--- a/clang/unittests/Analysis/ExprMutationAnalyzerTest.cpp
+++ b/clang/unittests/Analysis/ExprMutationAnalyzerTest.cpp
@@ -348,15 +348,12 @@ TEST(ExprMutationAnalyzerTest, DependentOperatorWithNonDependentOperand) {
// The expression to check may not be the dependent operand in a dependent
// operator.
- // Explicitly adding the conversion operator to int for `Stream` to make the
- // explicit instantiation (required due to windows' delayed template parsing
- // pre C++20) of `f` work without compile errors. Writing an `operator<<` for
- // `Stream` would make the `x << t` expression a CXXOperatorCallExpr, not a
- // BinaryOperator.
- const auto AST = buildASTFromCode(
- "struct Stream { operator int(); };"
- "template <typename T> void f() { T t; Stream x; x << t; }"
- "void foo() { f<int>(); }");
+ // Explicitly not declaring a (templated) stream operator
+ // so the `<<` is a `binaryOperator` with a dependent type.
+ const auto AST = buildASTFromCodeWithArgs(
+ "struct Stream { };"
+ "template <typename T> void f() { T t; Stream x; x << t; }",
+ {"-fno-delayed-template-parsing"});
const auto Results =
match(withEnclosingCompound(declRefTo("x")), AST->getASTContext());
EXPECT_THAT(mutatedBy(Results, AST.get()), ElementsAre("x << t"));
>From 9518580c6354aaf907339f30cacdaef10b01a5c2 Mon Sep 17 00:00:00 2001
From: Julian Schmidt <44101708+5chmidti at users.noreply.github.com>
Date: Mon, 13 Nov 2023 00:14:21 +0100
Subject: [PATCH 5/6] combine release note entries
---
clang-tools-extra/docs/ReleaseNotes.rst | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index bb75c9a3ce08125..0cf16b046aebe24 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -307,11 +307,9 @@ Changes in existing checks
- Improved :doc:`misc-const-correctness
<clang-tidy/checks/misc/const-correctness>` check to avoid false positive when
using pointer to member function.
-
-- Improved :doc:`misc-const-correctness
- <clang-tidy/checks/misc/const-correctness>` check to not warn on uses in
- type-dependent binary operators, when the variable that is being
- looked at, is not the dependent operand.
+ Additionally, the check no longer emits a diagnostic when
+ a variable that is not type-dependent is an operand of a
+ type-dependent binary operator.
- Improved :doc:`misc-include-cleaner
<clang-tidy/checks/misc/include-cleaner>` check by adding option
>From f5ad699d675ea8186c494bc67a136e89c68c9f96 Mon Sep 17 00:00:00 2001
From: Julian Schmidt <44101708+5chmidti at users.noreply.github.com>
Date: Mon, 13 Nov 2023 21:25:51 +0100
Subject: [PATCH 6/6] don't start a new line for a sentence
---
clang-tools-extra/docs/ReleaseNotes.rst | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index 0cf16b046aebe24..0aa56ca4e956a24 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -306,9 +306,8 @@ Changes in existing checks
- Improved :doc:`misc-const-correctness
<clang-tidy/checks/misc/const-correctness>` check to avoid false positive when
- using pointer to member function.
- Additionally, the check no longer emits a diagnostic when
- a variable that is not type-dependent is an operand of a
+ using pointer to member function. Additionally, the check no longer emits
+ a diagnostic when a variable that is not type-dependent is an operand of a
type-dependent binary operator.
- Improved :doc:`misc-include-cleaner
More information about the cfe-commits
mailing list