https://github.com/flovent updated https://github.com/llvm/llvm-project/pull/160971
>From fea611f78b31afb861228e0566b02b515bda1d67 Mon Sep 17 00:00:00 2001 From: flovent <[email protected]> Date: Sat, 27 Sep 2025 10:13:09 +0800 Subject: [PATCH 1/2] [clang-tidy] Fix false positives about references in `misc-const-correctness` --- clang-tools-extra/docs/ReleaseNotes.rst | 4 +++ .../const-correctness-pointer-as-pointers.cpp | 15 +++++++++++ clang/lib/Analysis/ExprMutationAnalyzer.cpp | 25 ++++++++++--------- .../Analysis/ExprMutationAnalyzerTest.cpp | 23 +++++++++++++++++ 4 files changed, 55 insertions(+), 12 deletions(-) diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index 9257dc6b98ba2..a6e4ed2edaebc 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -309,6 +309,10 @@ Changes in existing checks - ``for`` loops are supported. +- Improved :doc:`misc-const-correctness + <clang-tidy/checks/misc/misc-const-correctness>` check to avoid false + positives when pointers is tranferred to non-const references. + - Improved :doc:`misc-header-include-cycle <clang-tidy/checks/misc/header-include-cycle>` check performance. diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-pointer-as-pointers.cpp b/clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-pointer-as-pointers.cpp index 2ef47266b02b0..bcd946e7404c1 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-pointer-as-pointers.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-pointer-as-pointers.cpp @@ -48,3 +48,18 @@ void ignore_const_alias() { p_local0 = &a[1]; } +void takeNonConstRef(int *&r); + +void ignoreNonConstRefOps() { + // init with non-const ref + int* p0 {nullptr}; + int*& r1 = p0; + + // non-const ref param + int* p1 {nullptr}; + takeNonConstRef(p1); + + // cast + int* p2 {nullptr}; + int*& r2 = (int*&)p2; +} diff --git a/clang/lib/Analysis/ExprMutationAnalyzer.cpp b/clang/lib/Analysis/ExprMutationAnalyzer.cpp index 3fcd3481c2d6b..1e376da1be83d 100644 --- a/clang/lib/Analysis/ExprMutationAnalyzer.cpp +++ b/clang/lib/Analysis/ExprMutationAnalyzer.cpp @@ -755,22 +755,23 @@ ExprMutationAnalyzer::Analyzer::findPointeeMemberMutation(const Expr *Exp) { const Stmt * ExprMutationAnalyzer::Analyzer::findPointeeToNonConst(const Expr *Exp) { - const auto NonConstPointerOrDependentType = - type(anyOf(nonConstPointerType(), isDependentType())); + const auto NonConstPointerOrNonConstRefOrDependentType = type( + anyOf(nonConstPointerType(), nonConstReferenceType(), isDependentType())); // assign const auto InitToNonConst = - varDecl(hasType(NonConstPointerOrDependentType), + varDecl(hasType(NonConstPointerOrNonConstRefOrDependentType), hasInitializer(expr(canResolveToExprPointee(Exp)).bind("stmt"))); - const auto AssignToNonConst = - binaryOperation(hasOperatorName("="), - hasLHS(expr(hasType(NonConstPointerOrDependentType))), - hasRHS(canResolveToExprPointee(Exp))); + const auto AssignToNonConst = binaryOperation( + hasOperatorName("="), + hasLHS(expr(hasType(NonConstPointerOrNonConstRefOrDependentType))), + hasRHS(canResolveToExprPointee(Exp))); // arguments like const auto ArgOfInstantiationDependent = allOf( hasAnyArgument(canResolveToExprPointee(Exp)), isInstantiationDependent()); - const auto ArgOfNonConstParameter = forEachArgumentWithParamType( - canResolveToExprPointee(Exp), NonConstPointerOrDependentType); + const auto ArgOfNonConstParameter = + forEachArgumentWithParamType(canResolveToExprPointee(Exp), + NonConstPointerOrNonConstRefOrDependentType); const auto CallLikeMatcher = anyOf(ArgOfNonConstParameter, ArgOfInstantiationDependent); const auto PassAsNonConstArg = @@ -779,9 +780,9 @@ ExprMutationAnalyzer::Analyzer::findPointeeToNonConst(const Expr *Exp) { parenListExpr(has(canResolveToExprPointee(Exp))), initListExpr(hasAnyInit(canResolveToExprPointee(Exp))))); // cast - const auto CastToNonConst = - explicitCastExpr(hasSourceExpression(canResolveToExprPointee(Exp)), - hasDestinationType(NonConstPointerOrDependentType)); + const auto CastToNonConst = explicitCastExpr( + hasSourceExpression(canResolveToExprPointee(Exp)), + hasDestinationType(NonConstPointerOrNonConstRefOrDependentType)); // capture // FIXME: false positive if the pointee does not change in lambda diff --git a/clang/unittests/Analysis/ExprMutationAnalyzerTest.cpp b/clang/unittests/Analysis/ExprMutationAnalyzerTest.cpp index 4e97174c17d95..95f8ae266ae10 100644 --- a/clang/unittests/Analysis/ExprMutationAnalyzerTest.cpp +++ b/clang/unittests/Analysis/ExprMutationAnalyzerTest.cpp @@ -1749,6 +1749,13 @@ TEST(ExprMutationAnalyzerTest, PointeeMutatedByInitToNonConst) { match(withEnclosingCompound(declRefTo("x")), AST->getASTContext()); EXPECT_TRUE(isPointeeMutated(Results, AST.get())); } + { + const std::string Code = "void f() { int* x = nullptr; int*& b = x; }"; + auto AST = buildASTFromCodeWithArgs(Code, {}); + auto Results = + match(withEnclosingCompound(declRefTo("x")), AST->getASTContext()); + EXPECT_TRUE(isPointeeMutated(Results, AST.get())); + } } TEST(ExprMutationAnalyzerTest, PointeeMutatedByAssignToNonConst) { @@ -1786,6 +1793,14 @@ TEST(ExprMutationAnalyzerTest, PointeeMutatedByPassAsArgument) { match(withEnclosingCompound(declRefTo("x")), AST->getASTContext()); EXPECT_TRUE(isPointeeMutated(Results, AST.get())); } + { + const std::string Code = + "void b(int *&); void f() { int* x = nullptr; b(x); }"; + auto AST = buildASTFromCodeWithArgs(Code, {}); + auto Results = + match(withEnclosingCompound(declRefTo("x")), AST->getASTContext()); + EXPECT_TRUE(isPointeeMutated(Results, AST.get())); + } } TEST(ExprMutationAnalyzerTest, PointeeMutatedByPassAsArgumentInConstruct) { @@ -1884,6 +1899,14 @@ TEST(ExprMutationAnalyzerTest, PointeeMutatedByExplicitCastToNonConst) { match(withEnclosingCompound(declRefTo("x")), AST->getASTContext()); EXPECT_TRUE(isPointeeMutated(Results, AST.get())); } + { + const std::string Code = + "void f() { int* x = nullptr; static_cast<int*&>(x); }"; + auto AST = buildASTFromCodeWithArgs(Code, {"-Wno-everything"}); + auto Results = + match(withEnclosingCompound(declRefTo("x")), AST->getASTContext()); + EXPECT_TRUE(isPointeeMutated(Results, AST.get())); + } } TEST(ExprMutationAnalyzerTest, PointeeMutatedByConstCastToNonConst) { >From 5976ad50784c61e2f47a7f86f6c3b49082973c24 Mon Sep 17 00:00:00 2001 From: flovent <[email protected]> Date: Sat, 27 Sep 2025 10:27:51 +0800 Subject: [PATCH 2/2] [NFC] Fix doc error --- clang-tools-extra/docs/ReleaseNotes.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index a6e4ed2edaebc..34e7ea7f9368b 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -310,7 +310,7 @@ Changes in existing checks - ``for`` loops are supported. - Improved :doc:`misc-const-correctness - <clang-tidy/checks/misc/misc-const-correctness>` check to avoid false + <clang-tidy/checks/misc/const-correctness>` check to avoid false positives when pointers is tranferred to non-const references. - Improved :doc:`misc-header-include-cycle _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
