From 88b5ddbf8e99c207e0f6796a138432a85d8ac443 Mon Sep 17 00:00:00 2001 From: Changqing Jing Date: Mon, 6 Oct 2025 18:47:34 +0800 Subject: [PATCH] [clang-tidy]misc-const-correctness fix fake positive when pointer is returned as none const --- .../const-correctness-pointer-as-pointers.cpp | 30 +++++++++++++++++++ clang/lib/Analysis/ExprMutationAnalyzer.cpp | 8 ++++- 2 files changed, 37 insertions(+), 1 deletion(-) 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..6a4cbfec614aa 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,33 @@ void ignore_const_alias() { p_local0 = &a[1]; } +void* ignore_const_return(){ + void* const p = nullptr; + return p; +} + +void const* const_return(){ + void * p = nullptr; + // CHECK-MESSAGES: [[@LINE-1]]:3: warning: pointee of variable 'p' of type 'void *' can be declared 'const' + // CHECK-FIXES: void const* p + return p; +} + +template +T* ignore_const_return_template(){ + T* const p = nullptr; + return p; +} + +template +T const* const_return_template(){ + T * p = nullptr; + // CHECK-MESSAGES: [[@LINE-1]]:3: warning: pointee of variable 'p' of type 'int *' can be declared 'const' + // CHECK-FIXES: T const* p + return p; +} + +void instantiate_return_templates() { + ignore_const_return_template(); + const_return_template(); +} diff --git a/clang/lib/Analysis/ExprMutationAnalyzer.cpp b/clang/lib/Analysis/ExprMutationAnalyzer.cpp index 3fcd3481c2d6b..c051212ff1e57 100644 --- a/clang/lib/Analysis/ExprMutationAnalyzer.cpp +++ b/clang/lib/Analysis/ExprMutationAnalyzer.cpp @@ -787,10 +787,16 @@ ExprMutationAnalyzer::Analyzer::findPointeeToNonConst(const Expr *Exp) { // FIXME: false positive if the pointee does not change in lambda const auto CaptureNoConst = lambdaExpr(hasCaptureInit(Exp)); + // Return statement in function with non-const pointer return type + const auto ReturnAsNonConst = returnStmt( + hasDescendant(equalsNode(Exp)), + hasAncestor(functionDecl(returns(NonConstPointerOrDependentType)))); + const auto Matches = match(stmt(anyOf(forEachDescendant( stmt(anyOf(AssignToNonConst, PassAsNonConstArg, - CastToNonConst, CaptureNoConst)) + CastToNonConst, CaptureNoConst, + ReturnAsNonConst)) .bind("stmt")), forEachDescendant(InitToNonConst))), Stm, Context);