1 | //RUN: %clang_analyze_cc1 -cc1 -std=c++11 -analyzer-checker=core,apiModeling.google.GTest,debug.ExprInspection %s -verify |
2 | //RUN: %clang_analyze_cc1 -cc1 -std=c++11 -analyzer-checker=core,apiModeling.google.GTest,debug.ExprInspection -DGTEST_VERSION_1_8_AND_LATER=1 %s -verify |
3 | |
4 | void clang_analyzer_eval(int); |
5 | void clang_analyzer_warnIfReached(); |
6 | |
7 | namespace std { |
8 | class string { |
9 | public: |
10 | ~string(); |
11 | const char *c_str(); |
12 | }; |
13 | } |
14 | |
15 | namespace testing { |
16 | |
17 | class Message { }; |
18 | class TestPartResult { |
19 | public: |
20 | enum Type { |
21 | kSuccess, |
22 | kNonFatalFailure, |
23 | kFatalFailure |
24 | }; |
25 | }; |
26 | |
27 | namespace internal { |
28 | |
29 | class AssertHelper { |
30 | public: |
31 | AssertHelper(TestPartResult::Type type, const char* file, int line, |
32 | const char* message); |
33 | ~AssertHelper(); |
34 | void operator=(const Message& message) const; |
35 | }; |
36 | |
37 | |
38 | template <typename T> |
39 | struct AddReference { typedef T& type; }; |
40 | template <typename T> |
41 | struct AddReference<T&> { typedef T& type; }; |
42 | template <typename From, typename To> |
43 | class ImplicitlyConvertible { |
44 | private: |
45 | static typename AddReference<From>::type MakeFrom(); |
46 | static char Helper(To); |
47 | static char (&Helper(...))[2]; |
48 | public: |
49 | static const bool value = |
50 | sizeof(Helper(ImplicitlyConvertible::MakeFrom())) == 1; |
51 | }; |
52 | template <typename From, typename To> |
53 | const bool ImplicitlyConvertible<From, To>::value; |
54 | template<bool> struct EnableIf; |
55 | template<> struct EnableIf<true> { typedef void type; }; |
56 | |
57 | } // end internal |
58 | |
59 | |
60 | class AssertionResult { |
61 | public: |
62 | |
63 | // The implementation for the copy constructor is not exposed in the |
64 | // interface. |
65 | AssertionResult(const AssertionResult& other); |
66 | |
67 | #if defined(GTEST_VERSION_1_8_AND_LATER) |
68 | template <typename T> |
69 | explicit AssertionResult( |
70 | const T& success, |
71 | typename internal::EnableIf< |
72 | !internal::ImplicitlyConvertible<T, AssertionResult>::value>::type* |
73 | /*enabler*/ = 0) |
74 | : success_(success) {} |
75 | #else |
76 | explicit AssertionResult(bool success) : success_(success) {} |
77 | #endif |
78 | |
79 | operator bool() const { return success_; } |
80 | |
81 | // The actual AssertionResult does not have an explicit destructor, but |
82 | // it does have a non-trivial member veriable, so we add a destructor here |
83 | // to force temporary cleanups. |
84 | ~AssertionResult(); |
85 | private: |
86 | |
87 | bool success_; |
88 | }; |
89 | |
90 | namespace internal { |
91 | std::string GetBoolAssertionFailureMessage( |
92 | const AssertionResult& assertion_result, |
93 | const char* expression_text, |
94 | const char* actual_predicate_value, |
95 | const char* expected_predicate_value); |
96 | } // end internal |
97 | |
98 | } // end testing |
99 | |
100 | #define GTEST_MESSAGE_AT_(file, line, message, result_type) \ |
101 | ::testing::internal::AssertHelper(result_type, file, line, message) \ |
102 | = ::testing::Message() |
103 | |
104 | #define GTEST_MESSAGE_(message, result_type) \ |
105 | GTEST_MESSAGE_AT_(__FILE__, __LINE__, message, result_type) |
106 | |
107 | #define GTEST_FATAL_FAILURE_(message) \ |
108 | return GTEST_MESSAGE_(message, ::testing::TestPartResult::kFatalFailure) |
109 | |
110 | #define GTEST_NONFATAL_FAILURE_(message) \ |
111 | GTEST_MESSAGE_(message, ::testing::TestPartResult::kNonFatalFailure) |
112 | |
113 | # define GTEST_AMBIGUOUS_ELSE_BLOCKER_ switch (0) case 0: default: |
114 | |
115 | #define GTEST_TEST_BOOLEAN_(expression, text, actual, expected, fail) \ |
116 | GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ |
117 | if (const ::testing::AssertionResult gtest_ar_ = \ |
118 | ::testing::AssertionResult(expression)) \ |
119 | ; \ |
120 | else \ |
121 | fail(::testing::internal::GetBoolAssertionFailureMessage(\ |
122 | gtest_ar_, text, #actual, #expected).c_str()) |
123 | |
124 | #define EXPECT_TRUE(condition) \ |
125 | GTEST_TEST_BOOLEAN_((condition), #condition, false, true, \ |
126 | GTEST_NONFATAL_FAILURE_) |
127 | #define ASSERT_TRUE(condition) \ |
128 | GTEST_TEST_BOOLEAN_((condition), #condition, false, true, \ |
129 | GTEST_FATAL_FAILURE_) |
130 | |
131 | #define ASSERT_FALSE(condition) \ |
132 | GTEST_TEST_BOOLEAN_(!(condition), #condition, true, false, \ |
133 | GTEST_FATAL_FAILURE_) |
134 | |
135 | void testAssertTrue(int *p) { |
136 | ASSERT_TRUE(p != nullptr); |
137 | EXPECT_TRUE(1 == *p); // no-warning |
138 | } |
139 | |
140 | void testAssertFalse(int *p) { |
141 | ASSERT_FALSE(p == nullptr); |
142 | EXPECT_TRUE(1 == *p); // no-warning |
143 | } |
144 | |
145 | void testConstrainState(int p) { |
146 | ASSERT_TRUE(p == 7); |
147 | |
148 | clang_analyzer_eval(p == 7); // expected-warning {{TRUE}} |
149 | |
150 | ASSERT_TRUE(false); |
151 | clang_analyzer_warnIfReached(); // no-warning |
152 | } |
153 | |
154 | void testAssertSymbolicPtr(const bool *b) { |
155 | ASSERT_TRUE(*b); // no-crash |
156 | |
157 | clang_analyzer_eval(*b); // expected-warning{{TRUE}} |
158 | } |
159 | |
160 | void testAssertSymbolicRef(const bool &b) { |
161 | ASSERT_TRUE(b); // no-crash |
162 | |
163 | clang_analyzer_eval(b); // expected-warning{{TRUE}} |
164 | } |
165 | |