blob: 77c0717a87b9a3da3346c37390845a1101ab6152 [file] [log] [blame]
Googlerbcfef622023-10-17 12:13:54 -07001// Part of the Crubit project, under the Apache License v2.0 with LLVM
2// Exceptions. See /LICENSE for license information.
3// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
4
5#include "nullability/pointer_nullability_matchers.h"
6
7#include "clang/ASTMatchers/ASTMatchFinder.h"
8#include "clang/Testing/TestAST.h"
9#include "llvm/ADT/StringRef.h"
10#include "third_party/llvm/llvm-project/third-party/unittest/googletest/include/gtest/gtest.h"
11
12namespace clang::tidy::nullability {
13namespace {
14
15using ast_matchers::match;
16
17template <typename MatcherT>
18bool matches(llvm::StringRef base_input, llvm::StringRef test_input,
19 MatcherT Matcher) {
20 TestAST InputAST(base_input.str() + test_input.str());
21 return !match(Matcher, InputAST.context()).empty();
22}
23
24TEST(PointerNullabilityTest, MatchMemberFunctions) {
25 llvm::StringRef Input(R"cc(
26 struct DummyStruct {
27 int *p;
28 };
29 class C {
30 public:
31 int *_Nullable get() const { return x; }
32 int *_Nullable get_member_in_parens() const { return (x); }
33 int *_Nullable get_this_in_parens() const { return (this)->x; }
34 int *_Nullable get(int i) const { return x; }
35 int *_Nullable get_nonconst() { return x; }
36 int *_Nullable get_external() { return ds.p; }
Googlere9a51b52023-10-25 08:41:19 -070037 void may_mutate(){};
Googlerbcfef622023-10-17 12:13:54 -070038
39 private:
40 int *x;
41 DummyStruct ds;
42 };
Googlere9a51b52023-10-25 08:41:19 -070043 C foo() { return C(); }
Googlerbcfef622023-10-17 12:13:54 -070044 )cc");
45
46 EXPECT_TRUE(matches(Input, "void target(){ C().get(); }",
47 isSupportedPointerAccessorCall()));
48 EXPECT_TRUE(matches(Input, "void target(){ C().get_member_in_parens(); }",
49 isSupportedPointerAccessorCall()));
50 EXPECT_TRUE(matches(Input, "void target(){ C().get_this_in_parens(); }",
51 isSupportedPointerAccessorCall()));
52 EXPECT_TRUE(matches(Input, "void target(){ C().get(0); }",
53 isSupportedPointerAccessorCall()));
54 EXPECT_TRUE(matches(Input, "void target(){ C().get_nonconst(); }",
55 isSupportedPointerAccessorCall()));
Googlere9a51b52023-10-25 08:41:19 -070056 EXPECT_TRUE(matches(Input, "void target(){ foo().get(); }",
57 isSupportedPointerAccessorCall()));
Googlerbcfef622023-10-17 12:13:54 -070058
Googlere9a51b52023-10-25 08:41:19 -070059 EXPECT_FALSE(matches(Input, "void target(){ C().may_mutate(); }",
Googlerbcfef622023-10-17 12:13:54 -070060 isSupportedPointerAccessorCall()));
61 EXPECT_FALSE(matches(Input, "void target(){ C().get_external(); }",
62 isSupportedPointerAccessorCall()));
63}
64
Googlerca74c792023-11-08 11:27:22 -080065TEST(PointerNullabilityTest, MatchConstMemberFunctions) {
66 llvm::StringRef Input(R"cc(
67 class C {
68 public:
69 int *_Nullable get() const;
70 int *_Nullable get(int i) const;
71 int *_Nullable get_with_default_arg(int i = 0) const;
72 int *_Nullable get_nonconst();
73 };
74 C foo() { return C(); }
75 )cc");
76 EXPECT_TRUE(matches(Input, "void target(){ C().get(); }",
77 isZeroParamConstMemberCall()));
78 EXPECT_TRUE(matches(Input, "void target(){ foo().get(); }",
79 isZeroParamConstMemberCall()));
80
81 EXPECT_FALSE(matches(Input, "void target(){ C().get(0); }",
82 isZeroParamConstMemberCall()));
83 EXPECT_FALSE(matches(Input, "void target(){ C().get_with_default_arg(); }",
84 isZeroParamConstMemberCall()));
85 EXPECT_FALSE(matches(Input, "void target(){ C().get_nonconst(); }",
86 isZeroParamConstMemberCall()));
87}
Googlerbcfef622023-10-17 12:13:54 -070088} // namespace
89} // namespace clang::tidy::nullability