[clang-tools-extra] [clang-tidy] Fix false positive in misc-redundant-expression with type aliases (PR #198085)
via cfe-commits
cfe-commits at lists.llvm.org
Sat May 16 06:10:00 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang-tools-extra
Author: Caevan Lin (voyager-jhk)
<details>
<summary>Changes</summary>
The `misc-redundant-expression` check previously flagged expressions as redundant if their underlying `DeclRefExpr` pointed to the same declaration. This caused false positives when comparing identical values accessed through distinct type aliases (sugared types).
This patch uses `printPretty` to compare the source-level spellings of the expressions, ensuring nested name specifiers and explicit template arguments are correctly differentiated.
Fixes #<!-- -->145415
---
Full diff: https://github.com/llvm/llvm-project/pull/198085.diff
2 Files Affected:
- (modified) clang-tools-extra/clang-tidy/misc/RedundantExpressionCheck.cpp (+17-3)
- (added) clang-tools-extra/test/clang-tidy/checkers/misc/redundant-expression-type-aliases.cpp (+24)
``````````diff
diff --git a/clang-tools-extra/clang-tidy/misc/RedundantExpressionCheck.cpp b/clang-tools-extra/clang-tidy/misc/RedundantExpressionCheck.cpp
index 9db297990b274..b1b6bcee4b118 100644
--- a/clang-tools-extra/clang-tidy/misc/RedundantExpressionCheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/RedundantExpressionCheck.cpp
@@ -19,6 +19,7 @@
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/SmallBitVector.h"
#include "llvm/Support/FormatVariadic.h"
+#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <cassert>
#include <cstdint>
@@ -97,9 +98,22 @@ static bool areEquivalentExpr(const Expr *Left, const Expr *Right) {
return false;
return cast<DependentScopeDeclRefExpr>(Left)->getQualifier() ==
cast<DependentScopeDeclRefExpr>(Right)->getQualifier();
- case Stmt::DeclRefExprClass:
- return cast<DeclRefExpr>(Left)->getDecl() ==
- cast<DeclRefExpr>(Right)->getDecl();
+ case Stmt::DeclRefExprClass: {
+ const auto *L = cast<DeclRefExpr>(Left);
+ const auto *R = cast<DeclRefExpr>(Right);
+
+ if (L->getDecl() != R->getDecl())
+ return false;
+
+ // Compare source-level spellings to safely differentiate sugared types.
+ std::string LStr, RStr;
+ llvm::raw_string_ostream LOS(LStr), ROS(RStr);
+
+ L->printPretty(LOS, nullptr, L->getDecl()->getASTContext().getPrintingPolicy());
+ R->printPretty(ROS, nullptr, R->getDecl()->getASTContext().getPrintingPolicy());
+
+ return LStr == RStr;
+ }
case Stmt::MemberExprClass:
return cast<MemberExpr>(Left)->getMemberDecl() ==
cast<MemberExpr>(Right)->getMemberDecl();
diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/redundant-expression-type-aliases.cpp b/clang-tools-extra/test/clang-tidy/checkers/misc/redundant-expression-type-aliases.cpp
new file mode 100644
index 0000000000000..2df04809d5b58
--- /dev/null
+++ b/clang-tools-extra/test/clang-tidy/checkers/misc/redundant-expression-type-aliases.cpp
@@ -0,0 +1,24 @@
+// RUN: %check_clang_tidy %s misc-redundant-expression %t -- -- -std=c++17
+
+namespace std {
+ template<class T, int N> struct array { };
+ template<class T> struct tuple_size;
+ template<class T, int N> struct tuple_size<array<T, N>> { static constexpr int value = N; };
+ template<class T> constexpr int tuple_size_v = tuple_size<T>::value;
+}
+
+using MonthArray = std::array<int, 12>;
+using ZodiacArray = std::array<int, 12>;
+
+void test() {
+ // False positive cases (Should NOT warn):
+ bool b1 = std::tuple_size<MonthArray>::value == std::tuple_size<ZodiacArray>::value;
+ bool b2 = std::tuple_size_v<MonthArray> == std::tuple_size_v<ZodiacArray>;
+
+ // True positive cases (Should warn):
+ bool b3 = std::tuple_size<MonthArray>::value == std::tuple_size<MonthArray>::value;
+ // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: both sides of operator are equivalent [misc-redundant-expression]
+
+ bool b4 = std::tuple_size_v<MonthArray> == std::tuple_size_v<MonthArray>;
+ // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: both sides of operator are equivalent [misc-redundant-expression]
+}
\ No newline at end of file
``````````
</details>
https://github.com/llvm/llvm-project/pull/198085
More information about the cfe-commits
mailing list