https://github.com/localspook updated 
https://github.com/llvm/llvm-project/pull/183882

>From 3ef31b2c41adbd0e2da2076f13532c36e9ab4a52 Mon Sep 17 00:00:00 2001
From: Victor Chernyakin <[email protected]>
Date: Fri, 27 Feb 2026 21:43:59 -0800
Subject: [PATCH] [clang] Make `IgnoreUnlessSpelledInSource` ignore `CallExpr`s
 more aggressively

---
 .../readability/redundant-casting.cpp         | 19 +++++++++++++++
 clang/lib/AST/Expr.cpp                        | 24 ++++---------------
 2 files changed, 23 insertions(+), 20 deletions(-)

diff --git 
a/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-casting.cpp 
b/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-casting.cpp
index 3e723b8b61d1d..67b65d2e7f799 100644
--- 
a/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-casting.cpp
+++ 
b/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-casting.cpp
@@ -13,6 +13,8 @@
 // RUN: %check_clang_tidy -std=c++20 -check-suffix=,ALIASES %s 
readability-redundant-casting %t -- \
 // RUN:   -config='{CheckOptions: { 
readability-redundant-casting.IgnoreTypeAliases: true }}' \
 // RUN:   -- -fno-delayed-template-parsing -D CXX_20=1
+// RUN: %check_clang_tidy -std=c++23-or-later -check-suffix=,CXX23 %s 
readability-redundant-casting %t -- \
+// RUN:   -- -fno-delayed-template-parsing
 
 struct A {};
 struct B : A {};
@@ -245,3 +247,20 @@ int g1() {
   return fp();
 }
 } // namespace gh170476
+
+
+#if __cplusplus >= 202302L
+
+struct S {
+  operator int(this const S&);
+};
+
+void testCastingWithExplicitObjectParameterConversionOperator() {
+  int i = int(S {});
+
+  int j = int(S {}.operator int());
+  // CHECK-MESSAGES-CXX23: :[[@LINE-1]]:11: warning: redundant explicit 
casting to the same type 'int' as the sub-expression, remove this casting 
[readability-redundant-casting]
+  // CHECK-FIXES-CXX23: int j = S {}.operator int();
+}
+
+#endif // __cplusplus >= 202302L
diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp
index 9632d88fae4e4..45daed276547d 100644
--- a/clang/lib/AST/Expr.cpp
+++ b/clang/lib/AST/Expr.cpp
@@ -2550,18 +2550,6 @@ Stmt *BlockExpr::getBody() {
 // Generic Expression Routines
 
//===----------------------------------------------------------------------===//
 
-/// Helper to determine wether \c E is a CXXConstructExpr constructing
-/// a DecompositionDecl. Used to skip Clang-generated calls to std::get
-/// for structured bindings.
-static bool IsDecompositionDeclRefExpr(const Expr *E) {
-  const auto *Unwrapped = E->IgnoreUnlessSpelledInSource();
-  const auto *Ref = dyn_cast<DeclRefExpr>(Unwrapped);
-  if (!Ref)
-    return false;
-
-  return isa_and_nonnull<DecompositionDecl>(Ref->getDecl());
-}
-
 bool Expr::isReadIfDiscardedInCPlusPlus11() const {
   // In C++11, discarded-value expressions of a certain form are special,
   // according to [expr]p10:
@@ -3178,10 +3166,11 @@ Expr *Expr::IgnoreUnlessSpelledInSource() {
   };
 
   // Used when Clang generates calls to std::get for decomposing
-  // structured bindings.
+  // structured bindings or for implicit calls to member functions
+  // with explicit object parameters.
   auto IgnoreImplicitCallSingleStep = [](Expr *E) {
     auto *C = dyn_cast<CallExpr>(E);
-    if (!C)
+    if (!C || isa<UserDefinedLiteral>(C))
       return E;
 
     // Looking for calls to a std::get, which usually just takes
@@ -3197,12 +3186,7 @@ Expr *Expr::IgnoreUnlessSpelledInSource() {
     if (A->getSourceRange() != E->getSourceRange())
       return E;
 
-    // If the argument refers to a DecompositionDecl construction,
-    // ignore it.
-    if (IsDecompositionDeclRefExpr(A))
-      return A;
-
-    return E;
+    return A;
   };
 
   return IgnoreExprNodes(

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

Reply via email to