https://github.com/voyager-jhk created 
https://github.com/llvm/llvm-project/pull/198085

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

>From 81180f57a1b47d18837bc971dc5364784b4409b5 Mon Sep 17 00:00:00 2001
From: voyager-jhk <[email protected]>
Date: Sat, 16 May 2026 20:50:59 +0800
Subject: [PATCH] [clang-tidy] Fix false positive in misc-redundant-expression
 with type aliases

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
---
 .../misc/RedundantExpressionCheck.cpp         | 20 +++++++++++++---
 .../redundant-expression-type-aliases.cpp     | 24 +++++++++++++++++++
 2 files changed, 41 insertions(+), 3 deletions(-)
 create mode 100644 
clang-tools-extra/test/clang-tidy/checkers/misc/redundant-expression-type-aliases.cpp

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

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to