================
@@ -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

Reply via email to