[clang] [clang][dataflow] Fix smart pointer accessor caching to handle aliases (PR #124964)
via cfe-commits
cfe-commits at lists.llvm.org
Wed Jan 29 10:39:11 PST 2025
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
More information about the cfe-commits
mailing list