1 /*
2  *  Created by Martin on 17/02/2017.
3  *
4  *  Distributed under the Boost Software License, Version 1.0. (See accompanying
5  *  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6  */
7 
8 #include <type_traits>
9 
10 // Setup for #1403 -- look for global overloads of operator << for classes
11 // in a different namespace.
12 #include <ostream>
13 
14 namespace foo {
15     struct helper_1403 {
operator ==foo::helper_140316         bool operator==(helper_1403) const { return true; }
17     };
18 }
19 
20 namespace bar {
21     template <typename... Ts>
22     struct TypeList {};
23 }
24 
25 #ifdef __GNUC__
26 #pragma GCC diagnostic ignored "-Wmissing-declarations"
27 #endif
operator <<(std::ostream & out,foo::helper_1403 const &)28 std::ostream& operator<<(std::ostream& out, foo::helper_1403 const&) {
29     return out << "[1403 helper]";
30 }
31 ///////////////////////////////
32 
33 #include "catch.hpp"
34 
35 #include <cstring>
36 
37 namespace { namespace CompilationTests {
38 
39 #ifndef COMPILATION_TEST_HELPERS_INCLUDED // Don't compile this more than once per TU
40 #define COMPILATION_TEST_HELPERS_INCLUDED
41 
42     // Comparison operators can return non-booleans.
43     // This is unusual, but should be supported.
44     struct logic_t {
operator <__anon04c7942f0111::CompilationTests::logic_t45         logic_t operator< (logic_t) const { return {}; }
operator <=__anon04c7942f0111::CompilationTests::logic_t46         logic_t operator<=(logic_t) const { return {}; }
operator >__anon04c7942f0111::CompilationTests::logic_t47         logic_t operator> (logic_t) const { return {}; }
operator >=__anon04c7942f0111::CompilationTests::logic_t48         logic_t operator>=(logic_t) const { return {}; }
operator ==__anon04c7942f0111::CompilationTests::logic_t49         logic_t operator==(logic_t) const { return {}; }
operator !=__anon04c7942f0111::CompilationTests::logic_t50         logic_t operator!=(logic_t) const { return {}; }
operator bool__anon04c7942f0111::CompilationTests::logic_t51         explicit operator bool() const { return true; }
52     };
53 
54 
55 // This is a minimal example for an issue we have found in 1.7.0
56     struct foo {
57         int i;
58     };
59 
60     template<typename T>
operator ==(const T & val,foo f)61     bool operator==(const T &val, foo f) {
62         return val == f.i;
63     }
64 
65     struct Y {
66         uint32_t v : 1;
67     };
68 
throws_int(bool b)69     void throws_int(bool b) {
70         if (b) {
71 #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
72             throw 1;
73 #else
74             std::terminate();
75 #endif
76         }
77     }
78 
79     template<typename T>
templated_tests(T t)80     bool templated_tests(T t) {
81         int a = 3;
82         REQUIRE(a == t);
83         CHECK(a == t);
84         REQUIRE_THROWS(throws_int(true));
85         CHECK_THROWS_AS(throws_int(true), int);
86         REQUIRE_NOTHROW(throws_int(false));
87 #ifndef CATCH_CONFIG_DISABLE_MATCHERS
88         REQUIRE_THAT("aaa", Catch::EndsWith("aaa"));
89 #endif
90         return true;
91     }
92 
93     struct A {
94     };
95 
operator <<(std::ostream & o,const A &)96     std::ostream &operator<<(std::ostream &o, const A &) { return o << 0; }
97 
98     struct B : private A {
operator ==__anon04c7942f0111::CompilationTests::B99         bool operator==(int) const { return true; }
100     };
101 
102 #ifdef __clang__
103 #pragma clang diagnostic push
104 #pragma clang diagnostic ignored "-Wunused-function"
105 #endif
106 #ifdef __GNUC__
107 // Note that because -~GCC~-, this warning cannot be silenced temporarily, by pushing diagnostic stack...
108 // Luckily it is firing in test files and thus can be silenced for the whole file, without losing much.
109 #pragma GCC diagnostic ignored "-Wunused-function"
110 #endif
111 
112     B f();
113 
114     std::ostream g();
115 
116 #ifdef __clang__
117 #pragma clang diagnostic pop
118 #endif
119 
120     template <typename, typename>
121     struct Fixture_1245 {};
122 
123 #endif
124 
125     TEST_CASE("#809") {
126         foo f;
127         f.i = 42;
128         REQUIRE(42 == f);
129     }
130 
131 
132 // ------------------------------------------------------------------
133 // Changes to REQUIRE_THROWS_AS made it stop working in a template in
134 // an unfixable way (as long as C++03 compatibility is being kept).
135 // To prevent these from happening in the future, this needs to compile
136 
137     TEST_CASE("#833") {
138         REQUIRE(templated_tests<int>(3));
139     }
140 
141 
142 // Test containing example where original stream insertable check breaks compilation
143 
144 
145     TEST_CASE("#872") {
146         A dummy;
147         CAPTURE(dummy);
148         B x;
149         REQUIRE (x == 4);
150     }
151 
152 
153     TEST_CASE("#1027") {
154         Y y{0};
155         REQUIRE(y.v == 0);
156         REQUIRE(0 == y.v);
157     }
158 
159     // Comparison operators can return non-booleans.
160     // This is unusual, but should be supported.
161     TEST_CASE("#1147") {
162         logic_t t1, t2;
163         REQUIRE(t1 == t2);
164         REQUIRE(t1 != t2);
165         REQUIRE(t1 <  t2);
166         REQUIRE(t1 >  t2);
167         REQUIRE(t1 <= t2);
168         REQUIRE(t1 >= t2);
169     }
170 
171     // unsigned array
172     TEST_CASE("#1238") {
173         unsigned char uarr[] = "123";
174         CAPTURE(uarr);
175         signed char sarr[] = "456";
176         CAPTURE(sarr);
177 
178         REQUIRE(std::memcmp(uarr, "123", sizeof(uarr)) == 0);
179         REQUIRE(std::memcmp(sarr, "456", sizeof(sarr)) == 0);
180     }
181 
182     TEST_CASE_METHOD((Fixture_1245<int, int>), "#1245", "[compilation]") {
183         SUCCEED();
184     }
185 
186     TEST_CASE("#1403", "[compilation]") {
187         ::foo::helper_1403 h1, h2;
188         REQUIRE(h1 == h2);
189     }
190 
191     TEST_CASE("Optionally static assertions", "[compilation]") {
192         STATIC_REQUIRE( std::is_void<void>::value );
193         STATIC_REQUIRE_FALSE( std::is_void<int>::value );
194     }
195 
196     TEST_CASE("#1548", "[compilation]") {
197         using namespace bar;
198         REQUIRE(std::is_same<TypeList<int>, TypeList<int>>::value);
199     }
200 
201     // #925
202     using signal_t = void (*) (void*);
203 
204     struct TestClass {
205         signal_t testMethod_uponComplete_arg = nullptr;
206     };
207 
208     namespace utility {
synchronizing_callback(void *)209         inline static void synchronizing_callback( void * ) { }
210     }
211 
212 #if defined (_MSC_VER)
213 #pragma warning(push)
214 // The function pointer comparison below triggers warning because of
215 // calling conventions
216 #pragma warning(disable:4244)
217 #endif
218     TEST_CASE("#925: comparing function pointer to function address failed to compile", "[!nonportable]" ) {
219         TestClass test;
220         REQUIRE(utility::synchronizing_callback != test.testMethod_uponComplete_arg);
221     }
222 #if defined (_MSC_VER)
223 #pragma warning(pop)
224 #endif
225 
226     TEST_CASE( "#1027: Bitfields can be captured" ) {
227         struct Y {
228             uint32_t v : 1;
229         };
230         Y y{ 0 };
231         REQUIRE( y.v == 0 );
232         REQUIRE( 0 == y.v );
233     }
234 
235 
236 }} // namespace CompilationTests
237 
238