================ @@ -273,6 +273,18 @@ void UnnecessaryCopyInitialization::registerMatchers(MatchFinder *Finder) { Finder->addMatcher(LocalVarCopiedFrom(declRefExpr( to(varDecl(hasLocalStorage()).bind(OldVarDeclId)))), this); + + auto DeclRefToConstVar = + declRefExpr(to(varDecl(anyOf(hasType(isConstQualified()), + hasType(references(isConstQualified())))) + .bind(OldVarDeclId))); + Finder->addMatcher( + LocalVarCopiedFrom( + memberExpr(hasObjectExpression(anyOf(hasDescendant(DeclRefToConstVar), ---------------- movie-travel-code wrote:
Hi @vbvictor , the original implementation only consider the `const_var` and `var` in `const_var.xxx.xxx.xxx.var`, If there is a `CXXMemberCallExpr()` in the middle, it will brings a lot of complex analyses and potential bugs, as shown below. ```cpp struct Name { std::string str; }; struct Person { Name n; Name& getNameLocalRef() const { Name localN; return localN; } const Name getNameConst() const { return n; } const Name& getNameConstRef() const { return n; } }; std::string foo(const Person& p) { // There is a bug here, i.e. use-after-stack, so the fix `const auto& str1 = p.getNameLocalRef().str;` is also incorrect. auto str1 = p.getNameLocalRef().str; auto str2 = p.getNameConst().str; auto str3 = p.getNameConstRef().str; return str1 + str2 + str3; } ``` So I filtered all the `MemExpr`s that contain `CXXMemberCallExpr`. Since there are no `CXXMemberCallExpr`s in the middle, the pure `MemberExpr` can guarantee constness of all the chain, I believe. https://github.com/llvm/llvm-project/pull/151936 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits