Check for name collisions with system header macros.
Fix places where using `I` for an identifier was causing conflicts
with complex.h.
Fixes
MODIFY
cmake/ThrustHeaderTesting.cmake
cmake/ThrustHeaderTesting.cmake
# .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)
@@ -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()

MODIFY
cmake/header_test.in
cmake/header_test.in
+// 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}>

MODIFY
dependencies/cub
dependencies/cub
-Subproject commit 2442f44532ffcc53298c7e3a298feb5134563860
+Subproject commit 8e0920136373e225b012533e35bc6a33e56a3677

MODIFY
thrust/iterator/constant_iterator.h
thrust/iterator/constant_iterator.h
@@ -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()

MODIFY
thrust/system/cuda/detail/sort.h
thrust/system/cuda/detail/sort.h
@@ -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

MODIFY
thrust/type_traits/integer_sequence.h
thrust/type_traits/integer_sequence.h
@@ -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;
}
@@ -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;
///////////////////////////////////////////////////////////////////////////////

Check for name collisions with system header macros.

Fix places where using `I` for an identifier was causing conflicts
with complex.h.

Fixes #1244.