xref: /llvm-project/clang/test/Analysis/gtest.cpp (revision a393e68b27fcc8b78256407c99c6179acea056fe)
1*a393e68bSGeorge Karpenkov //RUN: %clang_analyze_cc1 -cc1 -std=c++11  -analyzer-checker=core,apiModeling.google.GTest,debug.ExprInspection %s -verify
2*a393e68bSGeorge Karpenkov //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
38beac285SDevin Coughlin 
4e17f6215SDevin Coughlin void clang_analyzer_eval(int);
5e17f6215SDevin Coughlin void clang_analyzer_warnIfReached();
68beac285SDevin Coughlin 
78beac285SDevin Coughlin namespace std {
88beac285SDevin Coughlin   class string {
98beac285SDevin Coughlin     public:
108beac285SDevin Coughlin     ~string();
118beac285SDevin Coughlin     const char *c_str();
128beac285SDevin Coughlin   };
138beac285SDevin Coughlin }
148beac285SDevin Coughlin 
158beac285SDevin Coughlin namespace testing {
168beac285SDevin Coughlin 
178beac285SDevin Coughlin class Message { };
188beac285SDevin Coughlin class TestPartResult {
198beac285SDevin Coughlin  public:
208beac285SDevin Coughlin   enum Type {
218beac285SDevin Coughlin     kSuccess,
228beac285SDevin Coughlin     kNonFatalFailure,
238beac285SDevin Coughlin     kFatalFailure
248beac285SDevin Coughlin   };
258beac285SDevin Coughlin };
268beac285SDevin Coughlin 
278beac285SDevin Coughlin namespace internal {
288beac285SDevin Coughlin 
298beac285SDevin Coughlin class AssertHelper {
308beac285SDevin Coughlin  public:
318beac285SDevin Coughlin   AssertHelper(TestPartResult::Type type, const char* file, int line,
328beac285SDevin Coughlin                const char* message);
338beac285SDevin Coughlin   ~AssertHelper();
348beac285SDevin Coughlin   void operator=(const Message& message) const;
358beac285SDevin Coughlin };
368beac285SDevin Coughlin 
378beac285SDevin Coughlin 
388beac285SDevin Coughlin template <typename T>
398beac285SDevin Coughlin struct AddReference { typedef T& type; };
408beac285SDevin Coughlin template <typename T>
418beac285SDevin Coughlin struct AddReference<T&> { typedef T& type; };
428beac285SDevin Coughlin template <typename From, typename To>
438beac285SDevin Coughlin class ImplicitlyConvertible {
448beac285SDevin Coughlin  private:
458beac285SDevin Coughlin   static typename AddReference<From>::type MakeFrom();
468beac285SDevin Coughlin   static char Helper(To);
478beac285SDevin Coughlin   static char (&Helper(...))[2];
488beac285SDevin Coughlin  public:
498beac285SDevin Coughlin   static const bool value =
508beac285SDevin Coughlin       sizeof(Helper(ImplicitlyConvertible::MakeFrom())) == 1;
518beac285SDevin Coughlin };
528beac285SDevin Coughlin template <typename From, typename To>
538beac285SDevin Coughlin const bool ImplicitlyConvertible<From, To>::value;
548beac285SDevin Coughlin template<bool> struct EnableIf;
558beac285SDevin Coughlin template<> struct EnableIf<true> { typedef void type; };
568beac285SDevin Coughlin 
578beac285SDevin Coughlin } // end internal
588beac285SDevin Coughlin 
598beac285SDevin Coughlin 
608beac285SDevin Coughlin class AssertionResult {
618beac285SDevin Coughlin public:
628beac285SDevin Coughlin 
638beac285SDevin Coughlin   // The implementation for the copy constructor is not exposed in the
648beac285SDevin Coughlin   // interface.
658beac285SDevin Coughlin   AssertionResult(const AssertionResult& other);
668beac285SDevin Coughlin 
678beac285SDevin Coughlin #if defined(GTEST_VERSION_1_8_AND_LATER)
688beac285SDevin Coughlin   template <typename T>
AssertionResult(const T & success,typename internal::EnableIf<!internal::ImplicitlyConvertible<T,AssertionResult>::value>::type * =0)698beac285SDevin Coughlin   explicit AssertionResult(
708beac285SDevin Coughlin       const T& success,
718beac285SDevin Coughlin       typename internal::EnableIf<
728beac285SDevin Coughlin           !internal::ImplicitlyConvertible<T, AssertionResult>::value>::type*
738beac285SDevin Coughlin           /*enabler*/ = 0)
748beac285SDevin Coughlin       : success_(success) {}
758beac285SDevin Coughlin #else
AssertionResult(bool success)768beac285SDevin Coughlin   explicit AssertionResult(bool success) : success_(success) {}
778beac285SDevin Coughlin #endif
788beac285SDevin Coughlin 
operator bool() const798beac285SDevin Coughlin   operator bool() const { return success_; }
808beac285SDevin Coughlin 
818beac285SDevin Coughlin   // The actual AssertionResult does not have an explicit destructor, but
828beac285SDevin Coughlin   // it does have a non-trivial member veriable, so we add a destructor here
838beac285SDevin Coughlin   // to force temporary cleanups.
848beac285SDevin Coughlin   ~AssertionResult();
858beac285SDevin Coughlin private:
868beac285SDevin Coughlin 
878beac285SDevin Coughlin   bool success_;
888beac285SDevin Coughlin };
898beac285SDevin Coughlin 
908beac285SDevin Coughlin namespace internal {
918beac285SDevin Coughlin std::string GetBoolAssertionFailureMessage(
928beac285SDevin Coughlin     const AssertionResult& assertion_result,
938beac285SDevin Coughlin     const char* expression_text,
948beac285SDevin Coughlin     const char* actual_predicate_value,
958beac285SDevin Coughlin     const char* expected_predicate_value);
968beac285SDevin Coughlin } // end internal
978beac285SDevin Coughlin 
988beac285SDevin Coughlin } // end testing
998beac285SDevin Coughlin 
1008beac285SDevin Coughlin #define GTEST_MESSAGE_AT_(file, line, message, result_type) \
1018beac285SDevin Coughlin   ::testing::internal::AssertHelper(result_type, file, line, message) \
1028beac285SDevin Coughlin     = ::testing::Message()
1038beac285SDevin Coughlin 
1048beac285SDevin Coughlin #define GTEST_MESSAGE_(message, result_type) \
1058beac285SDevin Coughlin   GTEST_MESSAGE_AT_(__FILE__, __LINE__, message, result_type)
1068beac285SDevin Coughlin 
1078beac285SDevin Coughlin #define GTEST_FATAL_FAILURE_(message) \
1088beac285SDevin Coughlin   return GTEST_MESSAGE_(message, ::testing::TestPartResult::kFatalFailure)
1098beac285SDevin Coughlin 
1108beac285SDevin Coughlin #define GTEST_NONFATAL_FAILURE_(message) \
1118beac285SDevin Coughlin   GTEST_MESSAGE_(message, ::testing::TestPartResult::kNonFatalFailure)
1128beac285SDevin Coughlin 
1138beac285SDevin Coughlin # define GTEST_AMBIGUOUS_ELSE_BLOCKER_ switch (0) case 0: default:
1148beac285SDevin Coughlin 
1158beac285SDevin Coughlin #define GTEST_TEST_BOOLEAN_(expression, text, actual, expected, fail) \
1168beac285SDevin Coughlin   GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
1178beac285SDevin Coughlin   if (const ::testing::AssertionResult gtest_ar_ = \
1188beac285SDevin Coughlin       ::testing::AssertionResult(expression)) \
1198beac285SDevin Coughlin     ; \
1208beac285SDevin Coughlin   else \
1218beac285SDevin Coughlin     fail(::testing::internal::GetBoolAssertionFailureMessage(\
1228beac285SDevin Coughlin         gtest_ar_, text, #actual, #expected).c_str())
1238beac285SDevin Coughlin 
1248beac285SDevin Coughlin #define EXPECT_TRUE(condition) \
1258beac285SDevin Coughlin   GTEST_TEST_BOOLEAN_((condition), #condition, false, true, \
1268beac285SDevin Coughlin                       GTEST_NONFATAL_FAILURE_)
1278beac285SDevin Coughlin #define ASSERT_TRUE(condition) \
1288beac285SDevin Coughlin   GTEST_TEST_BOOLEAN_((condition), #condition, false, true, \
1298beac285SDevin Coughlin                       GTEST_FATAL_FAILURE_)
1308beac285SDevin Coughlin 
1318beac285SDevin Coughlin #define ASSERT_FALSE(condition) \
1328beac285SDevin Coughlin   GTEST_TEST_BOOLEAN_(!(condition), #condition, true, false, \
1338beac285SDevin Coughlin                       GTEST_FATAL_FAILURE_)
1348beac285SDevin Coughlin 
testAssertTrue(int * p)1358beac285SDevin Coughlin void testAssertTrue(int *p) {
1368beac285SDevin Coughlin   ASSERT_TRUE(p != nullptr);
1378beac285SDevin Coughlin   EXPECT_TRUE(1 == *p); // no-warning
1388beac285SDevin Coughlin }
1398beac285SDevin Coughlin 
testAssertFalse(int * p)1408beac285SDevin Coughlin void testAssertFalse(int *p) {
1418beac285SDevin Coughlin   ASSERT_FALSE(p == nullptr);
1428beac285SDevin Coughlin   EXPECT_TRUE(1 == *p); // no-warning
1438beac285SDevin Coughlin }
144e17f6215SDevin Coughlin 
testConstrainState(int p)145e17f6215SDevin Coughlin void testConstrainState(int p) {
146e17f6215SDevin Coughlin   ASSERT_TRUE(p == 7);
147e17f6215SDevin Coughlin 
148e17f6215SDevin Coughlin   clang_analyzer_eval(p == 7); // expected-warning {{TRUE}}
149e17f6215SDevin Coughlin 
150e17f6215SDevin Coughlin   ASSERT_TRUE(false);
151e17f6215SDevin Coughlin   clang_analyzer_warnIfReached(); // no-warning
152e17f6215SDevin Coughlin }
1539445b89cSArtem Dergachev 
testAssertSymbolicPtr(const bool * b)1549445b89cSArtem Dergachev void testAssertSymbolicPtr(const bool *b) {
1559445b89cSArtem Dergachev   ASSERT_TRUE(*b); // no-crash
1569445b89cSArtem Dergachev 
1579a209ad1SArtem Dergachev   clang_analyzer_eval(*b); // expected-warning{{TRUE}}
1589445b89cSArtem Dergachev }
1599445b89cSArtem Dergachev 
testAssertSymbolicRef(const bool & b)1609445b89cSArtem Dergachev void testAssertSymbolicRef(const bool &b) {
1619445b89cSArtem Dergachev   ASSERT_TRUE(b); // no-crash
1629445b89cSArtem Dergachev 
1639a209ad1SArtem Dergachev   clang_analyzer_eval(b); // expected-warning{{TRUE}}
1649445b89cSArtem Dergachev }
165