File: Compilation.tests.cpp

package info (click to toggle)
log4cplus 2.0.8-1.1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 11,592 kB
  • sloc: cpp: 53,091; sh: 10,537; ansic: 1,845; python: 1,226; perl: 263; makefile: 209; xml: 85; objc: 59
file content (269 lines) | stat: -rw-r--r-- 6,914 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
/*
 *  Created by Martin on 17/02/2017.
 *
 *  Distributed under the Boost Software License, Version 1.0. (See accompanying
 *  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 */

#include <type_traits>

// Setup for #1403 -- look for global overloads of operator << for classes
// in a different namespace.
#include <ostream>

namespace foo {
    struct helper_1403 {
        bool operator==(helper_1403) const { return true; }
    };
}

namespace bar {
    template <typename... Ts>
    struct TypeList {};
}

#ifdef __GNUC__
#pragma GCC diagnostic ignored "-Wmissing-declarations"
#endif
std::ostream& operator<<(std::ostream& out, foo::helper_1403 const&) {
    return out << "[1403 helper]";
}
///////////////////////////////

#include "catch.hpp"

#include <cstring>

namespace { namespace CompilationTests {

#ifndef COMPILATION_TEST_HELPERS_INCLUDED // Don't compile this more than once per TU
#define COMPILATION_TEST_HELPERS_INCLUDED

    // Comparison operators can return non-booleans.
    // This is unusual, but should be supported.
    struct logic_t {
        logic_t operator< (logic_t) const { return {}; }
        logic_t operator<=(logic_t) const { return {}; }
        logic_t operator> (logic_t) const { return {}; }
        logic_t operator>=(logic_t) const { return {}; }
        logic_t operator==(logic_t) const { return {}; }
        logic_t operator!=(logic_t) const { return {}; }
        explicit operator bool() const { return true; }
    };


// This is a minimal example for an issue we have found in 1.7.0
    struct foo {
        int i;
    };

    template<typename T>
    bool operator==(const T &val, foo f) {
        return val == f.i;
    }

    struct Y {
        uint32_t v : 1;
    };

    void throws_int(bool b) {
        if (b) {
            throw 1;
        }
    }

    template<typename T>
    bool templated_tests(T t) {
        int a = 3;
        REQUIRE(a == t);
        CHECK(a == t);
        REQUIRE_THROWS(throws_int(true));
        CHECK_THROWS_AS(throws_int(true), int);
        REQUIRE_NOTHROW(throws_int(false));
#ifndef CATCH_CONFIG_DISABLE_MATCHERS
        REQUIRE_THAT("aaa", Catch::EndsWith("aaa"));
#endif
        return true;
    }

    struct A {
    };

    std::ostream &operator<<(std::ostream &o, const A &) { return o << 0; }

    struct B : private A {
        bool operator==(int) const { return true; }
    };

#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-function"
#endif
#ifdef __GNUC__
// Note that because -~GCC~-, this warning cannot be silenced temporarily, by pushing diagnostic stack...
// Luckily it is firing in test files and thus can be silenced for the whole file, without losing much.
#pragma GCC diagnostic ignored "-Wunused-function"
#endif

    B f();

    std::ostream g();

#ifdef __clang__
#pragma clang diagnostic pop
#endif

    template <typename, typename>
    struct Fixture_1245 {};

#endif

    TEST_CASE("#809") {
        foo f;
        f.i = 42;
        REQUIRE(42 == f);
    }


// ------------------------------------------------------------------
// Changes to REQUIRE_THROWS_AS made it stop working in a template in
// an unfixable way (as long as C++03 compatibility is being kept).
// To prevent these from happening in the future, this needs to compile

    TEST_CASE("#833") {
        REQUIRE(templated_tests<int>(3));
    }


// Test containing example where original stream insertable check breaks compilation


    TEST_CASE("#872") {
        A dummy;
        CAPTURE(dummy);
        B x;
        REQUIRE (x == 4);
    }


    TEST_CASE("#1027") {
        Y y{0};
        REQUIRE(y.v == 0);
        REQUIRE(0 == y.v);
    }

    // Comparison operators can return non-booleans.
    // This is unusual, but should be supported.
    TEST_CASE("#1147") {
        logic_t t1, t2;
        REQUIRE(t1 == t2);
        REQUIRE(t1 != t2);
        REQUIRE(t1 <  t2);
        REQUIRE(t1 >  t2);
        REQUIRE(t1 <= t2);
        REQUIRE(t1 >= t2);
    }

    // unsigned array
    TEST_CASE("#1238") {
        unsigned char uarr[] = "123";
        CAPTURE(uarr);
        signed char sarr[] = "456";
        CAPTURE(sarr);

        REQUIRE(std::memcmp(uarr, "123", sizeof(uarr)) == 0);
        REQUIRE(std::memcmp(sarr, "456", sizeof(sarr)) == 0);
    }

    TEST_CASE_METHOD((Fixture_1245<int, int>), "#1245", "[compilation]") {
        SUCCEED();
    }

    TEST_CASE("#1403", "[compilation]") {
        ::foo::helper_1403 h1, h2;
        REQUIRE(h1 == h2);
    }

    TEST_CASE("Optionally static assertions", "[compilation]") {
        STATIC_REQUIRE( std::is_void<void>::value );
        STATIC_REQUIRE_FALSE( std::is_void<int>::value );
    }

    TEST_CASE("#1548", "[compilation]") {
        using namespace bar;
        REQUIRE(std::is_same<TypeList<int>, TypeList<int>>::value);
    }

    // #925
    using signal_t = void (*) (void*);

    struct TestClass {
        signal_t testMethod_uponComplete_arg = nullptr;
    };

    namespace utility {
        inline static void synchronizing_callback( void * ) { }
    }

#if defined (_MSC_VER)
#pragma warning(push)
// The function pointer comparison below triggers warning because of
// calling conventions
#pragma warning(disable:4244)
#endif
    TEST_CASE("#925: comparing function pointer to function address failed to compile", "[!nonportable]" ) {
        TestClass test;
        REQUIRE(utility::synchronizing_callback != test.testMethod_uponComplete_arg);
    }
#if defined (_MSC_VER)
#pragma warning(pop)
#endif

    TEST_CASE( "#1027: Bitfields can be captured" ) {
        struct Y {
            uint32_t v : 1;
        };
        Y y{ 0 };
        REQUIRE( y.v == 0 );
        REQUIRE( 0 == y.v );
    }

    TEST_CASE("Lambdas in assertions") {
        REQUIRE([]() { return true; }());
    }

}} // namespace CompilationTests

namespace {
    struct HasBitOperators {
        int value;

        friend HasBitOperators operator| (HasBitOperators lhs, HasBitOperators rhs) {
            return { lhs.value | rhs.value };
        }
        friend HasBitOperators operator& (HasBitOperators lhs, HasBitOperators rhs) {
            return { lhs.value & rhs.value };
        }
        friend HasBitOperators operator^ (HasBitOperators lhs, HasBitOperators rhs) {
            return { lhs.value ^ rhs.value };
        }
        explicit operator bool() const {
            return !!value;
        }

        friend std::ostream& operator<<(std::ostream& out, HasBitOperators val) {
            out << "Val: " << val.value;
            return out;
        }
    };
}

TEST_CASE("Assertion macros support bit operators and bool conversions", "[compilation][bitops]") {
    HasBitOperators lhs{ 1 }, rhs{ 2 };
    REQUIRE(lhs | rhs);
    REQUIRE_FALSE(lhs & rhs);
    REQUIRE(HasBitOperators{ 1 } & HasBitOperators{ 1 });
    REQUIRE(lhs ^ rhs);
    REQUIRE_FALSE(lhs ^ lhs);
}