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

Commit

Permalink
Check for name collisions with system header macros.
Browse files Browse the repository at this point in the history
Fix places where using `I` for an identifier was causing conflicts
with complex.h.

Fixes #1244.
  • Loading branch information
alliepiper committed Sep 9, 2020
1 parent ff00c81 commit 691b021
Show file tree
Hide file tree
Showing 6 changed files with 79 additions and 15 deletions.
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

0 comments on commit 691b021

Please sign in to comment.