151c0b2f7Stbbdev /*
2*3e7d8e7fSPavel Kumbrasev Copyright (c) 2005-2023 Intel Corporation
351c0b2f7Stbbdev
451c0b2f7Stbbdev Licensed under the Apache License, Version 2.0 (the "License");
551c0b2f7Stbbdev you may not use this file except in compliance with the License.
651c0b2f7Stbbdev You may obtain a copy of the License at
751c0b2f7Stbbdev
851c0b2f7Stbbdev http://www.apache.org/licenses/LICENSE-2.0
951c0b2f7Stbbdev
1051c0b2f7Stbbdev Unless required by applicable law or agreed to in writing, software
1151c0b2f7Stbbdev distributed under the License is distributed on an "AS IS" BASIS,
1251c0b2f7Stbbdev WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1351c0b2f7Stbbdev See the License for the specific language governing permissions and
1451c0b2f7Stbbdev limitations under the License.
1551c0b2f7Stbbdev */
1651c0b2f7Stbbdev
1751c0b2f7Stbbdev //! \file test_tbb_header.cpp
1851c0b2f7Stbbdev //! \brief Test for [all] specification
1951c0b2f7Stbbdev
2051c0b2f7Stbbdev /**
2151c0b2f7Stbbdev This test ensures that tbb.h brings in all the public TBB interface definitions,
2251c0b2f7Stbbdev and if all the necessary symbols are exported from the library.
2351c0b2f7Stbbdev
2451c0b2f7Stbbdev Most of the checks happen at the compilation or link phases.
2551c0b2f7Stbbdev **/
2651c0b2f7Stbbdev
27b15aabb3Stbbdev #if __INTEL_COMPILER && _MSC_VER
28b15aabb3Stbbdev #pragma warning(disable : 2586) // decorated name length exceeded, name was truncated
29b15aabb3Stbbdev #endif
30b15aabb3Stbbdev
3155f9b178SIvan Kochin #ifndef NOMINMAX
3255f9b178SIvan Kochin #define NOMINMAX
3355f9b178SIvan Kochin #endif // NOMINMAX
3455f9b178SIvan Kochin
3551c0b2f7Stbbdev #define __TBB_NO_IMPLICIT_LINKAGE 1
3651c0b2f7Stbbdev
3751c0b2f7Stbbdev
3851c0b2f7Stbbdev #if __TBB_TEST_SECONDARY
3951c0b2f7Stbbdev // Test _DEBUG macro custom definitions.
4051c0b2f7Stbbdev #if TBB_USE_DEBUG
4151c0b2f7Stbbdev #ifdef _DEBUG
4251c0b2f7Stbbdev #undef _DEBUG
4351c0b2f7Stbbdev #endif /* _DEBUG */
4451c0b2f7Stbbdev // Check that empty value successfully enables the debug mode.
4551c0b2f7Stbbdev #define _DEBUG
4651c0b2f7Stbbdev static bool isDebugExpected = true;
4751c0b2f7Stbbdev #else
4851c0b2f7Stbbdev // Check that zero value does not enable the debug mode.
4951c0b2f7Stbbdev #define _DEBUG 0x0
5051c0b2f7Stbbdev static bool isDebugExpected = false;
5151c0b2f7Stbbdev #endif /* TBB_USE_DEBUG */
5251c0b2f7Stbbdev #define DO_TEST_DEBUG_MACRO 1
5351c0b2f7Stbbdev #else
5451c0b2f7Stbbdev // Test default definitions of _DEBUG.
5551c0b2f7Stbbdev #if _DEBUG
5651c0b2f7Stbbdev static bool isDebugExpected = true;
5751c0b2f7Stbbdev #define DO_TEST_DEBUG_MACRO 1
5851c0b2f7Stbbdev #elif _MSC_VER
5951c0b2f7Stbbdev // for MSVC, _DEBUG not defined indicates a release mode.
6051c0b2f7Stbbdev static bool isDebugExpected = false;
6151c0b2f7Stbbdev #define DO_TEST_DEBUG_MACRO 1
6251c0b2f7Stbbdev #endif /* _DEBUG */
6351c0b2f7Stbbdev #endif /* __TBB_TEST_SECONDARY */
6451c0b2f7Stbbdev
6551c0b2f7Stbbdev #if DO_TEST_DEBUG_MACRO
6651c0b2f7Stbbdev // Reset TBB_USE_DEBUG defined in makefiles.
6751c0b2f7Stbbdev #undef TBB_USE_DEBUG
6851c0b2f7Stbbdev #endif /* DO_TEST_DEBUG_MACRO */
6951c0b2f7Stbbdev #define __TBB_CONFIG_PREPROC_ONLY _MSC_VER // For MSVC, prevent including standard headers in tbb_config.h
70bf1f2ab6SIlya Isaev #include "common/config.h"
71bf1f2ab6SIlya Isaev
7249e08aacStbbdev #include "oneapi/tbb/detail/_config.h"
7351c0b2f7Stbbdev
7451c0b2f7Stbbdev #if !TBB_USE_DEBUG && defined(_DEBUG)
7551c0b2f7Stbbdev // TBB_USE_DEBUG is 0 but _DEBUG is defined, it means that _DEBUG is 0
7651c0b2f7Stbbdev // MSVC C++ headers consider any definition of _DEBUG, including 0, as debug mode
7751c0b2f7Stbbdev #undef _DEBUG
7851c0b2f7Stbbdev #endif /* !TBB_USE_DEBUG && defined(_DEBUG) */
7951c0b2f7Stbbdev
8051c0b2f7Stbbdev #include "tbb/tbb.h"
8151c0b2f7Stbbdev
8251c0b2f7Stbbdev #if !__TBB_TEST_SECONDARY
8351c0b2f7Stbbdev #include "common/test.h"
8451c0b2f7Stbbdev #endif
8551c0b2f7Stbbdev
8651c0b2f7Stbbdev static volatile size_t g_sink;
8751c0b2f7Stbbdev
8851c0b2f7Stbbdev #define TestTypeDefinitionPresence( Type ) g_sink = sizeof(tbb::Type);
8951c0b2f7Stbbdev #define TestTypeDefinitionPresence2(TypeStart, TypeEnd) g_sink = sizeof(tbb::TypeStart,TypeEnd);
9051c0b2f7Stbbdev #define TestTypeDefinitionPresence3(TypeStart, TypeMid, TypeEnd) g_sink = sizeof(tbb::TypeStart,TypeMid,TypeEnd);
9151c0b2f7Stbbdev #define TestFuncDefinitionPresence(Fn, Args, ReturnType) { ReturnType (*pfn)Args = &tbb::Fn; (void)pfn; }
9251c0b2f7Stbbdev
9351c0b2f7Stbbdev struct Body {
operator ()Body9451c0b2f7Stbbdev void operator() () const {}
9551c0b2f7Stbbdev };
9651c0b2f7Stbbdev struct Body1 {
operator ()Body19751c0b2f7Stbbdev void operator() ( int ) const {}
9851c0b2f7Stbbdev };
9951c0b2f7Stbbdev struct Body1a { // feeder body for parallel_do
operator ()Body1a10051c0b2f7Stbbdev void operator() ( int, tbb::feeder<int>& ) const {}
10151c0b2f7Stbbdev };
102478de5b1Stbbdev struct Body1b { // binary operator for reduction
operator ()Body1b10351c0b2f7Stbbdev int operator() ( const int, const int ) const { return 0; }
10451c0b2f7Stbbdev };
105478de5b1Stbbdev struct Body1bc { // binary operator for comparison
operator ()Body1bc106478de5b1Stbbdev bool operator() (const int, const int) const { return false; }
107478de5b1Stbbdev };
10851c0b2f7Stbbdev struct Body2 {
Body2Body210951c0b2f7Stbbdev Body2 () {}
Body2Body211051c0b2f7Stbbdev Body2 ( const Body2&, tbb::split ) {}
operator ()Body211151c0b2f7Stbbdev void operator() ( const tbb::blocked_range<int>& ) const {}
joinBody211251c0b2f7Stbbdev void join( const Body2& ) {}
11351c0b2f7Stbbdev };
11451c0b2f7Stbbdev struct Body2a { // for lambda-friendly parallel_reduce
operator ()Body2a11551c0b2f7Stbbdev int operator() ( const tbb::blocked_range<int>&, const int ) const { return 0; }
11651c0b2f7Stbbdev };
11751c0b2f7Stbbdev struct Body3 { // for parallel_scan
Body3Body311851c0b2f7Stbbdev Body3 () {}
Body3Body311951c0b2f7Stbbdev Body3 ( const Body3&, tbb::split ) {}
operator ()Body312051c0b2f7Stbbdev void operator() ( const tbb::blocked_range2d<int>&, tbb::pre_scan_tag ) const {}
operator ()Body312151c0b2f7Stbbdev void operator() ( const tbb::blocked_range2d<int>&, tbb::final_scan_tag ) const {}
reverse_joinBody312251c0b2f7Stbbdev void reverse_join( Body3& ) {}
assignBody312351c0b2f7Stbbdev void assign( const Body3& ) {}
12451c0b2f7Stbbdev };
12551c0b2f7Stbbdev struct Body3a { // for lambda-friednly parallel_scan
operator ()Body3a12651c0b2f7Stbbdev int operator() ( const tbb::blocked_range<int>&, const int, bool ) const { return 0; }
12751c0b2f7Stbbdev };
12851c0b2f7Stbbdev struct Msg {};
12951c0b2f7Stbbdev
13051c0b2f7Stbbdev // Test if all the necessary symbols are exported for the exceptions thrown by TBB.
13151c0b2f7Stbbdev // Missing exports result either in link error or in runtime assertion failure.
13251c0b2f7Stbbdev #include <stdexcept>
13351c0b2f7Stbbdev
13451c0b2f7Stbbdev template <typename E>
TestExceptionClassExports(const E & exc,tbb::detail::exception_id eid)13551c0b2f7Stbbdev void TestExceptionClassExports ( const E& exc, tbb::detail::exception_id eid ) {
13651c0b2f7Stbbdev CHECK( eid < tbb::detail::exception_id::last_entry );
13751c0b2f7Stbbdev #if TBB_USE_EXCEPTIONS
13851c0b2f7Stbbdev for ( int i = 0; i < 2; ++i ) {
13951c0b2f7Stbbdev try {
14051c0b2f7Stbbdev if ( i == 0 )
14151c0b2f7Stbbdev throw exc;
14251c0b2f7Stbbdev else
14351c0b2f7Stbbdev tbb::detail::throw_exception( eid );
14451c0b2f7Stbbdev }
14551c0b2f7Stbbdev catch ( E& e ) {
14651c0b2f7Stbbdev CHECK_MESSAGE( e.what(), "Missing what() string" );
14751c0b2f7Stbbdev }
14851c0b2f7Stbbdev catch ( ... ) {
14951c0b2f7Stbbdev CHECK_MESSAGE( false, "Unrecognized exception. Likely RTTI related exports are missing" );
15051c0b2f7Stbbdev }
15151c0b2f7Stbbdev }
15251c0b2f7Stbbdev #else /* TBB_USE_EXCEPTIONS */
15351c0b2f7Stbbdev (void)exc;
15451c0b2f7Stbbdev #endif /* TBB_USE_EXCEPTIONS */
15551c0b2f7Stbbdev }
15651c0b2f7Stbbdev
TestExceptionClassesExports()15751c0b2f7Stbbdev static void TestExceptionClassesExports () {
15851c0b2f7Stbbdev TestExceptionClassExports( std::bad_alloc(), tbb::detail::exception_id::bad_alloc );
15951c0b2f7Stbbdev TestExceptionClassExports( tbb::bad_last_alloc(), tbb::detail::exception_id::bad_last_alloc );
16051c0b2f7Stbbdev TestExceptionClassExports( std::invalid_argument("test"), tbb::detail::exception_id::nonpositive_step );
16151c0b2f7Stbbdev TestExceptionClassExports( std::out_of_range("test"), tbb::detail::exception_id::out_of_range );
16251c0b2f7Stbbdev TestExceptionClassExports( tbb::missing_wait(), tbb::detail::exception_id::missing_wait );
16351c0b2f7Stbbdev TestExceptionClassExports( std::out_of_range("test"), tbb::detail::exception_id::invalid_load_factor );
16451c0b2f7Stbbdev TestExceptionClassExports( std::length_error("test"), tbb::detail::exception_id::reservation_length_error );
16551c0b2f7Stbbdev TestExceptionClassExports( std::out_of_range("test"), tbb::detail::exception_id::invalid_key );
16651c0b2f7Stbbdev TestExceptionClassExports( tbb::user_abort(), tbb::detail::exception_id::user_abort );
16751c0b2f7Stbbdev TestExceptionClassExports( std::runtime_error("test"), tbb::detail::exception_id::bad_tagged_msg_cast );
16851c0b2f7Stbbdev }
16951c0b2f7Stbbdev
17051c0b2f7Stbbdev #if __TBB_CPF_BUILD
17151c0b2f7Stbbdev // These names are only tested in "preview" configuration
17251c0b2f7Stbbdev // When a feature becomes fully supported, its names should be moved to the main test
TestPreviewNames()17351c0b2f7Stbbdev static void TestPreviewNames() {
17451c0b2f7Stbbdev TestTypeDefinitionPresence2( blocked_rangeNd<int,4> );
17551c0b2f7Stbbdev TestTypeDefinitionPresence2( concurrent_lru_cache<int, int> );
17651c0b2f7Stbbdev TestTypeDefinitionPresence( isolated_task_group );
17751c0b2f7Stbbdev }
17851c0b2f7Stbbdev #endif
17951c0b2f7Stbbdev
DefinitionPresence()18051c0b2f7Stbbdev static void DefinitionPresence() {
18151c0b2f7Stbbdev TestTypeDefinitionPresence( cache_aligned_allocator<int> );
18251c0b2f7Stbbdev TestTypeDefinitionPresence( tbb_hash_compare<int> );
18351c0b2f7Stbbdev TestTypeDefinitionPresence2( concurrent_hash_map<int, int> );
18451c0b2f7Stbbdev TestTypeDefinitionPresence2( concurrent_unordered_map<int, int> );
18551c0b2f7Stbbdev TestTypeDefinitionPresence2( concurrent_unordered_multimap<int, int> );
18651c0b2f7Stbbdev TestTypeDefinitionPresence( concurrent_unordered_set<int> );
18751c0b2f7Stbbdev TestTypeDefinitionPresence( concurrent_unordered_multiset<int> );
18851c0b2f7Stbbdev TestTypeDefinitionPresence2( concurrent_map<int, int> );
18951c0b2f7Stbbdev TestTypeDefinitionPresence2( concurrent_multimap<int, int> );
19051c0b2f7Stbbdev TestTypeDefinitionPresence( concurrent_set<int> );
19151c0b2f7Stbbdev TestTypeDefinitionPresence( concurrent_multiset<int> );
19251c0b2f7Stbbdev TestTypeDefinitionPresence( concurrent_bounded_queue<int> );
19351c0b2f7Stbbdev TestTypeDefinitionPresence( concurrent_queue<int> );
19451c0b2f7Stbbdev TestTypeDefinitionPresence( concurrent_priority_queue<int> );
19551c0b2f7Stbbdev TestTypeDefinitionPresence( concurrent_vector<int> );
19651c0b2f7Stbbdev TestTypeDefinitionPresence( combinable<int> );
19751c0b2f7Stbbdev TestTypeDefinitionPresence( enumerable_thread_specific<int> );
19851c0b2f7Stbbdev /* Flow graph names */
19951c0b2f7Stbbdev TestTypeDefinitionPresence( flow::graph );
20051c0b2f7Stbbdev TestTypeDefinitionPresence( flow::continue_msg );
20151c0b2f7Stbbdev TestTypeDefinitionPresence2(flow::tagged_msg<int, int> );
20251c0b2f7Stbbdev TestFuncDefinitionPresence( flow::make_edge, (tbb::flow::sender<Msg>&, tbb::flow::receiver<Msg>&), void );
20351c0b2f7Stbbdev TestFuncDefinitionPresence( flow::remove_edge, (tbb::flow::sender<Msg>&, tbb::flow::receiver<Msg>&), void );
20451c0b2f7Stbbdev typedef std::tuple<int, int> intpair;
20551c0b2f7Stbbdev TestTypeDefinitionPresence( flow::input_node<int> );
20651c0b2f7Stbbdev TestTypeDefinitionPresence3(flow::function_node<int, int, tbb::flow::rejecting> );
20751c0b2f7Stbbdev TestTypeDefinitionPresence3(flow::multifunction_node<int, intpair, tbb::flow::queueing> );
20851c0b2f7Stbbdev TestTypeDefinitionPresence3(flow::async_node<int, int, tbb::flow::queueing_lightweight> );
20951c0b2f7Stbbdev TestTypeDefinitionPresence2(flow::continue_node<int, tbb::flow::lightweight> );
21051c0b2f7Stbbdev TestTypeDefinitionPresence2(flow::join_node<intpair, tbb::flow::reserving> );
21151c0b2f7Stbbdev TestTypeDefinitionPresence2(flow::join_node<intpair, tbb::flow::key_matching<int> > );
21251c0b2f7Stbbdev TestTypeDefinitionPresence( flow::split_node<intpair> );
21351c0b2f7Stbbdev TestTypeDefinitionPresence( flow::overwrite_node<int> );
21451c0b2f7Stbbdev TestTypeDefinitionPresence( flow::write_once_node<int> );
21551c0b2f7Stbbdev TestTypeDefinitionPresence( flow::broadcast_node<int> );
21651c0b2f7Stbbdev TestTypeDefinitionPresence( flow::buffer_node<int> );
21751c0b2f7Stbbdev TestTypeDefinitionPresence( flow::queue_node<int> );
21851c0b2f7Stbbdev TestTypeDefinitionPresence( flow::sequencer_node<int> );
21951c0b2f7Stbbdev TestTypeDefinitionPresence( flow::priority_queue_node<int> );
22051c0b2f7Stbbdev TestTypeDefinitionPresence( flow::limiter_node<int> );
22151c0b2f7Stbbdev TestTypeDefinitionPresence2(flow::indexer_node<int, int> );
22251c0b2f7Stbbdev TestTypeDefinitionPresence2(flow::composite_node<std::tuple<int>, std::tuple<int> > );
22351c0b2f7Stbbdev /* Mutex names */
22451c0b2f7Stbbdev TestTypeDefinitionPresence( null_mutex );
22551c0b2f7Stbbdev TestTypeDefinitionPresence( null_rw_mutex );
22651c0b2f7Stbbdev TestTypeDefinitionPresence( queuing_mutex );
22751c0b2f7Stbbdev TestTypeDefinitionPresence( queuing_rw_mutex );
22851c0b2f7Stbbdev TestTypeDefinitionPresence( spin_mutex );
22951c0b2f7Stbbdev TestTypeDefinitionPresence( spin_rw_mutex );
230*3e7d8e7fSPavel Kumbrasev TestTypeDefinitionPresence( mutex );
231*3e7d8e7fSPavel Kumbrasev TestTypeDefinitionPresence( rw_mutex );
23251c0b2f7Stbbdev TestTypeDefinitionPresence( speculative_spin_mutex );
23351c0b2f7Stbbdev TestTypeDefinitionPresence( speculative_spin_rw_mutex );
23451c0b2f7Stbbdev TestTypeDefinitionPresence( task_group_context );
23551c0b2f7Stbbdev TestTypeDefinitionPresence( task_group );
23651c0b2f7Stbbdev /* Algorithm related names */
23751c0b2f7Stbbdev TestTypeDefinitionPresence( blocked_range<int> );
23851c0b2f7Stbbdev TestTypeDefinitionPresence( blocked_range2d<int> );
23951c0b2f7Stbbdev TestTypeDefinitionPresence( blocked_range3d<int> );
240cf0a6739SIlya Isaev TestTypeDefinitionPresence( collaborative_once_flag );
241cf0a6739SIlya Isaev TestFuncDefinitionPresence( collaborative_call_once, (tbb::collaborative_once_flag&, const Body&), void );
24251c0b2f7Stbbdev TestFuncDefinitionPresence( parallel_invoke, (const Body&, const Body&, const Body&), void );
24351c0b2f7Stbbdev TestFuncDefinitionPresence( parallel_for_each, (int*, int*, const Body1&), void );
24451c0b2f7Stbbdev TestFuncDefinitionPresence( parallel_for, (int, int, int, const Body1&), void );
24551c0b2f7Stbbdev TestFuncDefinitionPresence( parallel_for, (const tbb::blocked_range<int>&, const Body2&, const tbb::simple_partitioner&), void );
24651c0b2f7Stbbdev TestFuncDefinitionPresence( parallel_reduce, (const tbb::blocked_range<int>&, const int&, const Body2a&, const Body1b&), int );
24751c0b2f7Stbbdev TestFuncDefinitionPresence( parallel_reduce, (const tbb::blocked_range<int>&, Body2&, tbb::affinity_partitioner&), void );
24851c0b2f7Stbbdev TestFuncDefinitionPresence( parallel_deterministic_reduce, (const tbb::blocked_range<int>&, const int&, const Body2a&, const Body1b&), int );
24951c0b2f7Stbbdev TestFuncDefinitionPresence( parallel_deterministic_reduce, (const tbb::blocked_range<int>&, Body2&, const tbb::static_partitioner&), void );
25051c0b2f7Stbbdev TestFuncDefinitionPresence( parallel_scan, (const tbb::blocked_range2d<int>&, Body3&, const tbb::auto_partitioner&), void );
25151c0b2f7Stbbdev TestFuncDefinitionPresence( parallel_scan, (const tbb::blocked_range<int>&, const int&, const Body3a&, const Body1b&), int );
25251c0b2f7Stbbdev typedef int intarray[10];
253478de5b1Stbbdev
25451c0b2f7Stbbdev TestFuncDefinitionPresence( parallel_sort, (int*, int*), void );
255478de5b1Stbbdev TestFuncDefinitionPresence( parallel_sort, (intarray&, const Body1bc&), void );
25651c0b2f7Stbbdev TestFuncDefinitionPresence( parallel_pipeline, (size_t, const tbb::filter<void,void>&), void );
25751c0b2f7Stbbdev TestFuncDefinitionPresence( parallel_invoke, (const Body&, const Body&, tbb::task_group_context&), void );
25851c0b2f7Stbbdev TestFuncDefinitionPresence( parallel_for_each, (const intarray&, const Body1a&, tbb::task_group_context&), void );
25951c0b2f7Stbbdev TestFuncDefinitionPresence( parallel_for, (int, int, const Body1&, const tbb::auto_partitioner&, tbb::task_group_context&), void );
26051c0b2f7Stbbdev TestFuncDefinitionPresence( parallel_for, (int, int, const Body1&, tbb::task_group_context&), void );
26151c0b2f7Stbbdev TestFuncDefinitionPresence( parallel_reduce, (const tbb::blocked_range<int>&, Body2&, const tbb::auto_partitioner&, tbb::task_group_context&), void );
26251c0b2f7Stbbdev TestFuncDefinitionPresence( parallel_reduce, (const tbb::blocked_range<int>&, Body2&, tbb::task_group_context&), void );
26351c0b2f7Stbbdev TestFuncDefinitionPresence( parallel_deterministic_reduce, (const tbb::blocked_range<int>&, Body2&, const tbb::simple_partitioner&, tbb::task_group_context&), void );
26451c0b2f7Stbbdev TestFuncDefinitionPresence( parallel_deterministic_reduce, (const tbb::blocked_range<int>&, Body2&, tbb::task_group_context&), void );
26551c0b2f7Stbbdev TestTypeDefinitionPresence( proportional_split );
26651c0b2f7Stbbdev
26751c0b2f7Stbbdev TestTypeDefinitionPresence( task_arena );
26851c0b2f7Stbbdev TestFuncDefinitionPresence( this_task_arena::current_thread_index, (), int );
26951c0b2f7Stbbdev TestFuncDefinitionPresence( this_task_arena::max_concurrency, (), int );
27049e08aacStbbdev TestFuncDefinitionPresence( info::numa_nodes, (), std::vector<tbb::numa_node_id> );
27149e08aacStbbdev TestFuncDefinitionPresence( info::default_concurrency, (tbb::numa_node_id), int );
27251c0b2f7Stbbdev TestTypeDefinitionPresence( task_scheduler_observer );
27351c0b2f7Stbbdev TestTypeDefinitionPresence( tbb_allocator<int> );
27451c0b2f7Stbbdev TestTypeDefinitionPresence( tick_count );
27551c0b2f7Stbbdev TestTypeDefinitionPresence( global_control );
27651c0b2f7Stbbdev
27751c0b2f7Stbbdev #if __TBB_CPF_BUILD
27851c0b2f7Stbbdev TestPreviewNames();
27951c0b2f7Stbbdev #endif
28051c0b2f7Stbbdev #ifdef DO_TEST_DEBUG_MACRO
28151c0b2f7Stbbdev #if TBB_USE_DEBUG
28251c0b2f7Stbbdev CHECK_MESSAGE( isDebugExpected, "Debug mode is observed while release mode is expected." );
28351c0b2f7Stbbdev #else
28451c0b2f7Stbbdev CHECK_MESSAGE( !isDebugExpected, "Release mode is observed while debug mode is expected." );
28551c0b2f7Stbbdev #endif /* TBB_USE_DEBUG */
28651c0b2f7Stbbdev #endif /* DO_TEST_DEBUG_MACRO */
28751c0b2f7Stbbdev TestExceptionClassesExports();
28851c0b2f7Stbbdev }
28951c0b2f7Stbbdev
29051c0b2f7Stbbdev #if __TBB_TEST_SECONDARY
29151c0b2f7Stbbdev /* This mode is used to produce a secondary object file that is linked with
29251c0b2f7Stbbdev the main one in order to detect "multiple definition" linker error.
29351c0b2f7Stbbdev */
Secondary()29451c0b2f7Stbbdev void Secondary() {
29551c0b2f7Stbbdev DefinitionPresence();
29651c0b2f7Stbbdev }
29751c0b2f7Stbbdev #else
29851c0b2f7Stbbdev //! Test for deifinition presence
29951c0b2f7Stbbdev //! \brief \ref interface
30051c0b2f7Stbbdev TEST_CASE("Test for deifinition presence") {
30151c0b2f7Stbbdev DefinitionPresence();
30251c0b2f7Stbbdev }
30351c0b2f7Stbbdev
30451c0b2f7Stbbdev void Secondary();
30551c0b2f7Stbbdev //! Test for "multiple definition" linker error
30651c0b2f7Stbbdev //! \brief \ref error_guessing
30751c0b2f7Stbbdev TEST_CASE("Test for multiple definition linker error") {
30851c0b2f7Stbbdev Secondary();
30951c0b2f7Stbbdev }
31051c0b2f7Stbbdev #endif
311