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>
AssertionResult(const T & success,typename internal::EnableIf<!internal::ImplicitlyConvertible<T,AssertionResult>::value>::type * =0)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
AssertionResult(bool success)76   explicit AssertionResult(bool success) : success_(success) {}
77 #endif
78 
operator bool() const79   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 
testAssertTrue(int * p)135 void testAssertTrue(int *p) {
136   ASSERT_TRUE(p != nullptr);
137   EXPECT_TRUE(1 == *p); // no-warning
138 }
139 
testAssertFalse(int * p)140 void testAssertFalse(int *p) {
141   ASSERT_FALSE(p == nullptr);
142   EXPECT_TRUE(1 == *p); // no-warning
143 }
144 
testConstrainState(int p)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 
testAssertSymbolicPtr(const bool * b)154 void testAssertSymbolicPtr(const bool *b) {
155   ASSERT_TRUE(*b); // no-crash
156 
157   clang_analyzer_eval(*b); // expected-warning{{TRUE}}
158 }
159 
testAssertSymbolicRef(const bool & b)160 void testAssertSymbolicRef(const bool &b) {
161   ASSERT_TRUE(b); // no-crash
162 
163   clang_analyzer_eval(b); // expected-warning{{TRUE}}
164 }
165