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
