llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: Jan Voung (jvoung) <details> <summary>Changes</summary> Check the canonical type in the matchers to handle aliases. For example std::optional uses add_pointer_t<...>. --- Full diff: https://github.com/llvm/llvm-project/pull/124964.diff 2 Files Affected: - (modified) clang/lib/Analysis/FlowSensitive/SmartPointerAccessorCaching.cpp (+11-8) - (modified) clang/unittests/Analysis/FlowSensitive/SmartPointerAccessorCachingTest.cpp (+52) ``````````diff diff --git a/clang/lib/Analysis/FlowSensitive/SmartPointerAccessorCaching.cpp b/clang/lib/Analysis/FlowSensitive/SmartPointerAccessorCaching.cpp index c58bd309545dbf..b73f9e2751449a 100644 --- a/clang/lib/Analysis/FlowSensitive/SmartPointerAccessorCaching.cpp +++ b/clang/lib/Analysis/FlowSensitive/SmartPointerAccessorCaching.cpp @@ -14,6 +14,7 @@ using ast_matchers::callee; using ast_matchers::cxxMemberCallExpr; using ast_matchers::cxxMethodDecl; using ast_matchers::cxxOperatorCallExpr; +using ast_matchers::hasCanonicalType; using ast_matchers::hasName; using ast_matchers::hasOverloadedOperatorName; using ast_matchers::ofClass; @@ -122,27 +123,29 @@ namespace clang::dataflow { ast_matchers::StatementMatcher isSmartPointerLikeOperatorStar() { return cxxOperatorCallExpr( hasOverloadedOperatorName("*"), - callee(cxxMethodDecl(parameterCountIs(0), returns(referenceType()), + callee(cxxMethodDecl(parameterCountIs(0), + returns(hasCanonicalType(referenceType())), ofClass(smartPointerClassWithGetOrValue())))); } ast_matchers::StatementMatcher isSmartPointerLikeOperatorArrow() { return cxxOperatorCallExpr( hasOverloadedOperatorName("->"), - callee(cxxMethodDecl(parameterCountIs(0), returns(pointerType()), + callee(cxxMethodDecl(parameterCountIs(0), + returns(hasCanonicalType(pointerType())), ofClass(smartPointerClassWithGetOrValue())))); } ast_matchers::StatementMatcher isSmartPointerLikeValueMethodCall() { - return cxxMemberCallExpr(callee( - cxxMethodDecl(parameterCountIs(0), returns(referenceType()), - hasName("value"), ofClass(smartPointerClassWithValue())))); + return cxxMemberCallExpr(callee(cxxMethodDecl( + parameterCountIs(0), returns(hasCanonicalType(referenceType())), + hasName("value"), ofClass(smartPointerClassWithValue())))); } ast_matchers::StatementMatcher isSmartPointerLikeGetMethodCall() { - return cxxMemberCallExpr(callee( - cxxMethodDecl(parameterCountIs(0), returns(pointerType()), hasName("get"), - ofClass(smartPointerClassWithGet())))); + return cxxMemberCallExpr(callee(cxxMethodDecl( + parameterCountIs(0), returns(hasCanonicalType(pointerType())), + hasName("get"), ofClass(smartPointerClassWithGet())))); } const FunctionDecl * diff --git a/clang/unittests/Analysis/FlowSensitive/SmartPointerAccessorCachingTest.cpp b/clang/unittests/Analysis/FlowSensitive/SmartPointerAccessorCachingTest.cpp index 3f75dff60ee5fc..18b9f80e32bbf1 100644 --- a/clang/unittests/Analysis/FlowSensitive/SmartPointerAccessorCachingTest.cpp +++ b/clang/unittests/Analysis/FlowSensitive/SmartPointerAccessorCachingTest.cpp @@ -190,5 +190,57 @@ TEST(SmartPointerAccessorCachingTest, MatchesWithValueAndNonConstOverloads) { isSmartPointerLikeValueMethodCall())); } +TEST(SmartPointerAccessorCachingTest, MatchesWithTypeAliases) { + llvm::StringRef Decls(R"cc( + template <class T> + struct HasGetAndValue { + using pointer_t = T*; + using reference_t = T&; + + const pointer_t operator->() const; + pointer_t operator->(); + const reference_t operator*() const; + reference_t operator*(); + const reference_t value() const; + reference_t value(); + const pointer_t get() const; + pointer_t get(); + }; + + struct S { int i; }; + )cc"); + + EXPECT_TRUE(matches( + Decls, + "int target(HasGetAndValue<S> &NonConst) { return (*NonConst).i; }", + isSmartPointerLikeOperatorStar())); + EXPECT_TRUE(matches( + Decls, + "int target(const HasGetAndValue<S> &Const) { return (*Const).i; }", + isSmartPointerLikeOperatorStar())); + EXPECT_TRUE(matches( + Decls, "int target(HasGetAndValue<S> &NonConst) { return NonConst->i; }", + isSmartPointerLikeOperatorArrow())); + EXPECT_TRUE(matches( + Decls, "int target(const HasGetAndValue<S> &Const) { return Const->i; }", + isSmartPointerLikeOperatorArrow())); + EXPECT_TRUE(matches( + Decls, + "int target(HasGetAndValue<S> &NonConst) { return NonConst.value().i; }", + isSmartPointerLikeValueMethodCall())); + EXPECT_TRUE(matches( + Decls, + "int target(const HasGetAndValue<S> &Const) { return Const.value().i; }", + isSmartPointerLikeValueMethodCall())); + EXPECT_TRUE(matches( + Decls, + "int target(HasGetAndValue<S> &NonConst) { return NonConst.get()->i; }", + isSmartPointerLikeGetMethodCall())); + EXPECT_TRUE(matches( + Decls, + "int target(const HasGetAndValue<S> &Const) { return Const.get()->i; }", + isSmartPointerLikeGetMethodCall())); +} + } // namespace } // namespace clang::dataflow `````````` </details> https://github.com/llvm/llvm-project/pull/124964 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits