forked from OSchip/llvm-project
				
			
		
			
				
	
	
		
			165 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			165 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			C++
		
	
	
	
| //RUN: %clang_analyze_cc1 -cc1 -std=c++11  -analyzer-checker=core,apiModeling.google.GTest,debug.ExprInspection %s -verify
 | |
| //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
 | |
| 
 | |
| void clang_analyzer_eval(int);
 | |
| void clang_analyzer_warnIfReached();
 | |
| 
 | |
| namespace std {
 | |
|   class string {
 | |
|     public:
 | |
|     ~string();
 | |
|     const char *c_str();
 | |
|   };
 | |
| }
 | |
| 
 | |
| namespace testing {
 | |
| 
 | |
| class Message { };
 | |
| class TestPartResult {
 | |
|  public:
 | |
|   enum Type {
 | |
|     kSuccess,
 | |
|     kNonFatalFailure,
 | |
|     kFatalFailure
 | |
|   };
 | |
| };
 | |
| 
 | |
| namespace internal {
 | |
| 
 | |
| class AssertHelper {
 | |
|  public:
 | |
|   AssertHelper(TestPartResult::Type type, const char* file, int line,
 | |
|                const char* message);
 | |
|   ~AssertHelper();
 | |
|   void operator=(const Message& message) const;
 | |
| };
 | |
| 
 | |
| 
 | |
| template <typename T>
 | |
| struct AddReference { typedef T& type; };
 | |
| template <typename T>
 | |
| struct AddReference<T&> { typedef T& type; };
 | |
| template <typename From, typename To>
 | |
| class ImplicitlyConvertible {
 | |
|  private:
 | |
|   static typename AddReference<From>::type MakeFrom();
 | |
|   static char Helper(To);
 | |
|   static char (&Helper(...))[2];
 | |
|  public:
 | |
|   static const bool value =
 | |
|       sizeof(Helper(ImplicitlyConvertible::MakeFrom())) == 1;
 | |
| };
 | |
| template <typename From, typename To>
 | |
| const bool ImplicitlyConvertible<From, To>::value;
 | |
| template<bool> struct EnableIf;
 | |
| template<> struct EnableIf<true> { typedef void type; };
 | |
| 
 | |
| } // end internal
 | |
| 
 | |
| 
 | |
| class AssertionResult {
 | |
| public:
 | |
| 
 | |
|   // The implementation for the copy constructor is not exposed in the
 | |
|   // interface.
 | |
|   AssertionResult(const AssertionResult& other);
 | |
| 
 | |
| #if defined(GTEST_VERSION_1_8_AND_LATER)
 | |
|   template <typename T>
 | |
|   explicit AssertionResult(
 | |
|       const T& success,
 | |
|       typename internal::EnableIf<
 | |
|           !internal::ImplicitlyConvertible<T, AssertionResult>::value>::type*
 | |
|           /*enabler*/ = 0)
 | |
|       : success_(success) {}
 | |
| #else
 | |
|   explicit AssertionResult(bool success) : success_(success) {}
 | |
| #endif
 | |
| 
 | |
|   operator bool() const { return success_; }
 | |
| 
 | |
|   // The actual AssertionResult does not have an explicit destructor, but
 | |
|   // it does have a non-trivial member veriable, so we add a destructor here
 | |
|   // to force temporary cleanups.
 | |
|   ~AssertionResult();
 | |
| private:
 | |
| 
 | |
|   bool success_;
 | |
| };
 | |
| 
 | |
| namespace internal {
 | |
| std::string GetBoolAssertionFailureMessage(
 | |
|     const AssertionResult& assertion_result,
 | |
|     const char* expression_text,
 | |
|     const char* actual_predicate_value,
 | |
|     const char* expected_predicate_value);
 | |
| } // end internal
 | |
| 
 | |
| } // end testing
 | |
| 
 | |
| #define GTEST_MESSAGE_AT_(file, line, message, result_type) \
 | |
|   ::testing::internal::AssertHelper(result_type, file, line, message) \
 | |
|     = ::testing::Message()
 | |
| 
 | |
| #define GTEST_MESSAGE_(message, result_type) \
 | |
|   GTEST_MESSAGE_AT_(__FILE__, __LINE__, message, result_type)
 | |
| 
 | |
| #define GTEST_FATAL_FAILURE_(message) \
 | |
|   return GTEST_MESSAGE_(message, ::testing::TestPartResult::kFatalFailure)
 | |
| 
 | |
| #define GTEST_NONFATAL_FAILURE_(message) \
 | |
|   GTEST_MESSAGE_(message, ::testing::TestPartResult::kNonFatalFailure)
 | |
| 
 | |
| # define GTEST_AMBIGUOUS_ELSE_BLOCKER_ switch (0) case 0: default:
 | |
| 
 | |
| #define GTEST_TEST_BOOLEAN_(expression, text, actual, expected, fail) \
 | |
|   GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
 | |
|   if (const ::testing::AssertionResult gtest_ar_ = \
 | |
|       ::testing::AssertionResult(expression)) \
 | |
|     ; \
 | |
|   else \
 | |
|     fail(::testing::internal::GetBoolAssertionFailureMessage(\
 | |
|         gtest_ar_, text, #actual, #expected).c_str())
 | |
| 
 | |
| #define EXPECT_TRUE(condition) \
 | |
|   GTEST_TEST_BOOLEAN_((condition), #condition, false, true, \
 | |
|                       GTEST_NONFATAL_FAILURE_)
 | |
| #define ASSERT_TRUE(condition) \
 | |
|   GTEST_TEST_BOOLEAN_((condition), #condition, false, true, \
 | |
|                       GTEST_FATAL_FAILURE_)
 | |
| 
 | |
| #define ASSERT_FALSE(condition) \
 | |
|   GTEST_TEST_BOOLEAN_(!(condition), #condition, true, false, \
 | |
|                       GTEST_FATAL_FAILURE_)
 | |
| 
 | |
| void testAssertTrue(int *p) {
 | |
|   ASSERT_TRUE(p != nullptr);
 | |
|   EXPECT_TRUE(1 == *p); // no-warning
 | |
| }
 | |
| 
 | |
| void testAssertFalse(int *p) {
 | |
|   ASSERT_FALSE(p == nullptr);
 | |
|   EXPECT_TRUE(1 == *p); // no-warning
 | |
| }
 | |
| 
 | |
| void testConstrainState(int p) {
 | |
|   ASSERT_TRUE(p == 7);
 | |
| 
 | |
|   clang_analyzer_eval(p == 7); // expected-warning {{TRUE}}
 | |
| 
 | |
|   ASSERT_TRUE(false);
 | |
|   clang_analyzer_warnIfReached(); // no-warning
 | |
| }
 | |
| 
 | |
| void testAssertSymbolicPtr(const bool *b) {
 | |
|   ASSERT_TRUE(*b); // no-crash
 | |
| 
 | |
|   clang_analyzer_eval(*b); // expected-warning{{TRUE}}
 | |
| }
 | |
| 
 | |
| void testAssertSymbolicRef(const bool &b) {
 | |
|   ASSERT_TRUE(b); // no-crash
 | |
| 
 | |
|   clang_analyzer_eval(b); // expected-warning{{TRUE}}
 | |
| }
 |