Skip to content
This repository has been archived by the owner on Mar 21, 2024. It is now read-only.

Check for name collisions with system header macros. #1270

Merged
merged 1 commit into from
Sep 9, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions cmake/ThrustHeaderTesting.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,14 @@
# .inl files are not globbed for, because they are not supposed to be used as public
# entrypoints.

# Meta target for all configs' header builds:
add_custom_target(thrust.all.headers)

foreach(thrust_target IN LISTS THRUST_TARGETS)
thrust_get_target_property(config_host ${thrust_target} HOST)
thrust_get_target_property(config_device ${thrust_target} DEVICE)
thrust_get_target_property(config_prefix ${thrust_target} PREFIX)
set(config_systems ${config_host} ${config_device})

string(TOLOWER "${config_host}" host_lower)
string(TOLOWER "${config_device}" device_lower)
Expand Down Expand Up @@ -115,5 +119,14 @@ foreach(thrust_target IN LISTS THRUST_TARGETS)
target_link_libraries(${headertest_target} PUBLIC ${thrust_target})
thrust_clone_target_properties(${headertest_target} ${thrust_target})

# Disable macro checks on TBB; the TBB atomic implementation uses `I` and
# our checks will issue false errors.
if ("TBB" IN_LIST config_systems)
target_compile_definitions(${headertest_target}
PRIVATE THRUST_IGNORE_MACRO_CHECKS
)
endif()

add_dependencies(thrust.all.headers ${headertest_target})
add_dependencies(${config_prefix}.all ${headertest_target})
endforeach()
51 changes: 51 additions & 0 deletions cmake/header_test.in
Original file line number Diff line number Diff line change
@@ -1,4 +1,55 @@
// This source file checks that:
// 1) Header <thrust/${header}> compiles without error.
// 2) Common macro collisions with platform/system headers are avoided.

// Turn off failures for certain configurations:
#define THRUST_CPP11_REQUIRED_NO_ERROR
#define THRUST_CPP14_REQUIRED_NO_ERROR
#define THRUST_MODERN_GCC_REQUIRED_NO_ERROR

#ifndef THRUST_IGNORE_MACRO_CHECKS

// Define THRUST_MACRO_CHECK(macro, header), which emits a diagnostic indicating
// a potential macro collision and halts.
//
// Hacky way to build a string, but it works on all tested platforms.
#define THRUST_MACRO_CHECK(MACRO, HEADER) \
THRUST_MACRO_CHECK_IMPL(Identifier MACRO should not be used from Thrust \
headers due to conflicts with HEADER.)

// Use raw platform checks instead of the THRUST_HOST_COMPILER macros since we
// don't want to #include any headers other than the one being tested.
//
// This is only implemented for MSVC/GCC/Clang.
#if defined(_MSC_VER) // MSVC

// Fake up an error for MSVC
#define THRUST_MACRO_CHECK_IMPL(msg) \
/* Print message that looks like an error: */ \
__pragma(message(__FILE__ ":" THRUST_MACRO_CHECK_IMPL0(__LINE__) \
": error: " #msg)) \
/* abort compilation due to static_assert or syntax error: */ \
static_assert(false, #msg);
#define THRUST_MACRO_CHECK_IMPL0(x) THRUST_MACRO_CHECK_IMPL1(x)
#define THRUST_MACRO_CHECK_IMPL1(x) #x

#elif defined(__clang__) || defined(__GNUC__)

// GCC/clang are easy:
#define THRUST_MACRO_CHECK_IMPL(msg) THRUST_MACRO_CHECK_IMPL0(GCC error #msg)
#define THRUST_MACRO_CHECK_IMPL0(expr) _Pragma(#expr)

#endif

// complex.h conflicts
#define I THRUST_MACRO_CHECK('I', complex.h)

// windows.h conflicts
// Disabling for now; we use min/max in many places, but since most
// projects build with NOMINMAX this doesn't seem to be high priority to fix.
//#define min(...) THRUST_MACRO_CHECK('min', windows.h)
//#define max(...) THRUST_MACRO_CHECK('max', windows.h)

#endif // THRUST_IGNORE_MACRO_CHECKS

#include <thrust/${header}>
2 changes: 1 addition & 1 deletion dependencies/cub
6 changes: 3 additions & 3 deletions thrust/iterator/constant_iterator.h
Original file line number Diff line number Diff line change
Expand Up @@ -217,11 +217,11 @@ template<typename Value,
*
* \see constant_iterator
*/
template<typename V, typename I>
template<typename ValueT, typename IndexT>
inline __host__ __device__
constant_iterator<V,I> make_constant_iterator(V x, I i = int())
constant_iterator<ValueT, IndexT> make_constant_iterator(ValueT x, IndexT i = int())
{
return constant_iterator<V,I>(x, i);
return constant_iterator<ValueT, IndexT>(x, i);
} // end make_constant_iterator()


Expand Down
10 changes: 5 additions & 5 deletions thrust/system/cuda/detail/sort.h
Original file line number Diff line number Diff line change
Expand Up @@ -312,18 +312,18 @@ namespace __merge_sort {
item_type (&items)[ITEMS_PER_THREAD])
{
#pragma unroll
for (int I = 0; I < ITEMS_PER_THREAD; ++I)
for (int i = 0; i < ITEMS_PER_THREAD; ++i)
{
#pragma unroll
for (int J = 1 & I; J < ITEMS_PER_THREAD - 1; J += 2)
for (int j = 1 & i; j < ITEMS_PER_THREAD - 1; j += 2)
{
if (compare_op(keys[J + 1], keys[J]))
if (compare_op(keys[j + 1], keys[j]))
{
using thrust::swap;
swap(keys[J], keys[J + 1]);
swap(keys[j], keys[j + 1]);
if (SORT_ITEMS::value)
{
swap(items[J], items[J + 1]);
swap(items[j], items[j + 1]);
}
}
} // inner loop
Expand Down
12 changes: 6 additions & 6 deletions thrust/type_traits/integer_sequence.h
Original file line number Diff line number Diff line change
Expand Up @@ -167,11 +167,11 @@ template <typename T, std::size_t N>
struct make_reversed_integer_sequence_impl;

// Add a new element to the front of an integer_sequence<>.
template <typename T, T I, typename Sequence>
template <typename T, T Value, typename Sequence>
struct integer_sequence_push_front_impl;

// Add a new element to the back of an integer_sequence<>.
template <typename T, T I, typename Sequence>
template <typename T, T Value, typename Sequence>
struct integer_sequence_push_back_impl;

}
Expand All @@ -189,14 +189,14 @@ using make_reversed_index_sequence =
make_reversed_integer_sequence<std::size_t, N>;

// Add a new element to the front of an integer_sequence<>.
template <typename T, T I, typename Sequence>
template <typename T, T Value, typename Sequence>
using integer_sequence_push_front =
typename detail::integer_sequence_push_front_impl<T, I, Sequence>::type;
typename detail::integer_sequence_push_front_impl<T, Value, Sequence>::type;

// Add a new element to the back of an integer_sequence<>.
template <typename T, T I, typename Sequence>
template <typename T, T Value, typename Sequence>
using integer_sequence_push_back =
typename detail::integer_sequence_push_back_impl<T, I, Sequence>::type;
typename detail::integer_sequence_push_back_impl<T, Value, Sequence>::type;

///////////////////////////////////////////////////////////////////////////////

Expand Down