Update 'restricted header' comments; avoid C++ headers in vector_test_target.cc
diff --git a/highwayhash/arch_specific.h b/highwayhash/arch_specific.h index 7698166..7419d8e 100644 --- a/highwayhash/arch_specific.h +++ b/highwayhash/arch_specific.h
@@ -15,8 +15,26 @@ #ifndef HIGHWAYHASH_ARCH_SPECIFIC_H_ #define HIGHWAYHASH_ARCH_SPECIFIC_H_ -// WARNING: compiled with different flags => must not define/instantiate any -// inline functions, nor include any headers that do - see instruction_sets.h. +// WARNING: this is a "restricted" header because it is included from +// translation units compiled with different flags. This header and its +// dependencies must not define any function unless it is static inline and/or +// within namespace HH_TARGET_NAME. +// +// Background: older GCC/Clang require flags such as -mavx2 before AVX2 SIMD +// intrinsics can be used. These intrinsics are only used within blocks that +// first verify CPU capabilities. However, the flag also allows the compiler to +// generate AVX2 code in other places. This can violate the One Definition Rule, +// which requires multiple instances of a function with external linkage +// (e.g. extern inline in a header) to be "equivalent". To prevent the resulting +// crashes on non-AVX2 CPUs, any header (transitively) included from a +// translation unit compiled with different flags is "restricted". This means +// all function definitions must have internal linkage (e.g. static inline), or +// reside in namespace HH_TARGET_NAME, which expands to a name unique to the +// current compiler flags. +// +// Most C system headers are safe to include, but C++ headers should generally +// be avoided because they often do not specify static linkage and cannot +// reliably be wrapped in a namespace. #include "highwayhash/compiler_specific.h"
diff --git a/highwayhash/compiler_specific.h b/highwayhash/compiler_specific.h index 3c25dd6..4789f9a 100644 --- a/highwayhash/compiler_specific.h +++ b/highwayhash/compiler_specific.h
@@ -15,8 +15,10 @@ #ifndef HIGHWAYHASH_COMPILER_SPECIFIC_H_ #define HIGHWAYHASH_COMPILER_SPECIFIC_H_ -// WARNING: compiled with different flags => must not define/instantiate any -// inline functions, nor include any headers that do - see instruction_sets.h. +// WARNING: this is a "restricted" header because it is included from +// translation units compiled with different flags. This header and its +// dependencies must not define any function unless it is static inline and/or +// within namespace HH_TARGET_NAME. See arch_specific.h for details. // Compiler
diff --git a/highwayhash/endianess.h b/highwayhash/endianess.h index d2e108d..69455b6 100644 --- a/highwayhash/endianess.h +++ b/highwayhash/endianess.h
@@ -15,8 +15,12 @@ #ifndef HIGHWAYHASH_ENDIANESS_H_ #define HIGHWAYHASH_ENDIANESS_H_ -#include <stdint.h> +// WARNING: this is a "restricted" header because it is included from +// translation units compiled with different flags. This header and its +// dependencies must not define any function unless it is static inline and/or +// within namespace HH_TARGET_NAME. See arch_specific.h for details. +#include <stdint.h> #if defined(BYTE_ORDER) && defined(LITTLE_ENDIAN) && defined(BIG_ENDIAN) @@ -100,5 +104,4 @@ } // namespace highwayhash - #endif // HIGHWAYHASH_ENDIANESS_H_
diff --git a/highwayhash/hh_avx2.cc b/highwayhash/hh_avx2.cc index 3549460..7e3ddff 100644 --- a/highwayhash/hh_avx2.cc +++ b/highwayhash/hh_avx2.cc
@@ -12,5 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +// WARNING: this is a "restricted" source file; avoid including any headers +// unless they are also restricted. See arch_specific.h for details. + #define HH_TARGET_NAME AVX2 #include "highwayhash/highwayhash_target.cc"
diff --git a/highwayhash/hh_avx2.h b/highwayhash/hh_avx2.h index aecbdaf..2912a31 100644 --- a/highwayhash/hh_avx2.h +++ b/highwayhash/hh_avx2.h
@@ -15,8 +15,10 @@ #ifndef HIGHWAYHASH_HH_AVX2_H_ #define HIGHWAYHASH_HH_AVX2_H_ -// WARNING: compiled with different flags => must not define/instantiate any -// inline functions, nor include any headers that do - see instruction_sets.h. +// WARNING: this is a "restricted" header because it is included from +// translation units compiled with different flags. This header and its +// dependencies must not define any function unless it is static inline and/or +// within namespace HH_TARGET_NAME. See arch_specific.h for details. #include "highwayhash/arch_specific.h" #include "highwayhash/compiler_specific.h"
diff --git a/highwayhash/hh_buffer.h b/highwayhash/hh_buffer.h index 6827d9b..5b1c83f 100644 --- a/highwayhash/hh_buffer.h +++ b/highwayhash/hh_buffer.h
@@ -17,6 +17,11 @@ // Helper functions used by hh_avx2 and hh_sse41. +// WARNING: this is a "restricted" header because it is included from +// translation units compiled with different flags. This header and its +// dependencies must not define any function unless it is static inline and/or +// within namespace HH_TARGET_NAME. See arch_specific.h for details. + #include "highwayhash/vector128.h" // For auto-dependency generation, we need to include all headers but not their
diff --git a/highwayhash/hh_portable.cc b/highwayhash/hh_portable.cc index 8e4c902..3e0de9e 100644 --- a/highwayhash/hh_portable.cc +++ b/highwayhash/hh_portable.cc
@@ -12,5 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +// WARNING: this is a "restricted" source file; avoid including any headers +// unless they are also restricted. See arch_specific.h for details. + #define HH_TARGET_NAME Portable #include "highwayhash/highwayhash_target.cc"
diff --git a/highwayhash/hh_portable.h b/highwayhash/hh_portable.h index 84a17be..11284de 100644 --- a/highwayhash/hh_portable.h +++ b/highwayhash/hh_portable.h
@@ -15,8 +15,10 @@ #ifndef HIGHWAYHASH_HH_PORTABLE_H_ #define HIGHWAYHASH_HH_PORTABLE_H_ -// WARNING: compiled with different flags => must not define/instantiate any -// inline functions, nor include any headers that do - see instruction_sets.h. +// WARNING: this is a "restricted" header because it is included from +// translation units compiled with different flags. This header and its +// dependencies must not define any function unless it is static inline and/or +// within namespace HH_TARGET_NAME. See arch_specific.h for details. #include "highwayhash/arch_specific.h" #include "highwayhash/compiler_specific.h"
diff --git a/highwayhash/hh_sse41.cc b/highwayhash/hh_sse41.cc index f414b67..9d6a0b9 100644 --- a/highwayhash/hh_sse41.cc +++ b/highwayhash/hh_sse41.cc
@@ -12,5 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +// WARNING: this is a "restricted" source file; avoid including any headers +// unless they are also restricted. See arch_specific.h for details. + #define HH_TARGET_NAME SSE41 #include "highwayhash/highwayhash_target.cc"
diff --git a/highwayhash/hh_sse41.h b/highwayhash/hh_sse41.h index e8ae957..a2a86da 100644 --- a/highwayhash/hh_sse41.h +++ b/highwayhash/hh_sse41.h
@@ -15,8 +15,10 @@ #ifndef HIGHWAYHASH_HH_SSE41_H_ #define HIGHWAYHASH_HH_SSE41_H_ -// WARNING: compiled with different flags => must not define/instantiate any -// inline functions, nor include any headers that do - see instruction_sets.h. +// WARNING: this is a "restricted" header because it is included from +// translation units compiled with different flags. This header and its +// dependencies must not define any function unless it is static inline and/or +// within namespace HH_TARGET_NAME. See arch_specific.h for details. #include "highwayhash/arch_specific.h" #include "highwayhash/compiler_specific.h"
diff --git a/highwayhash/hh_types.h b/highwayhash/hh_types.h index 8ff0f8e..f350d70 100644 --- a/highwayhash/hh_types.h +++ b/highwayhash/hh_types.h
@@ -16,8 +16,10 @@ #define HIGHWAYHASH_HH_TYPES_H_ // WARNING: included from c_bindings => must be C-compatible. -// WARNING: compiled with different flags => must not define/instantiate any -// inline functions, nor include any headers that do - see instruction_sets.h. +// WARNING: this is a "restricted" header because it is included from +// translation units compiled with different flags. This header and its +// dependencies must not define any function unless it is static inline and/or +// within namespace HH_TARGET_NAME. See arch_specific.h for details. #include <stddef.h> // size_t #include <stdint.h>
diff --git a/highwayhash/highwayhash.h b/highwayhash/highwayhash.h index 82aa4a5..cee1c31 100644 --- a/highwayhash/highwayhash.h +++ b/highwayhash/highwayhash.h
@@ -15,9 +15,6 @@ #ifndef HIGHWAYHASH_HIGHWAYHASH_H_ #define HIGHWAYHASH_HIGHWAYHASH_H_ -// WARNING: compiled with different flags => must not define/instantiate any -// inline functions, nor include any headers that do - see instruction_sets.h. - // This header's templates are useful for inlining into other CPU-specific code: // template<TargetBits Target> CodeUsingHash() { HighwayHashT<Target>(...); }, // and can also be instantiated with HH_TARGET when callers don't care about the @@ -25,6 +22,11 @@ // highwayhash_target wrapper. Use that instead if you need to detect the best // available implementation at runtime. +// WARNING: this is a "restricted" header because it is included from +// translation units compiled with different flags. This header and its +// dependencies must not define any function unless it is static inline and/or +// within namespace HH_TARGET_NAME. See arch_specific.h for details. + #include "highwayhash/arch_specific.h" #include "highwayhash/compiler_specific.h" #include "highwayhash/hh_types.h"
diff --git a/highwayhash/highwayhash_target.cc b/highwayhash/highwayhash_target.cc index 6bc913d..b87f0cb 100644 --- a/highwayhash/highwayhash_target.cc +++ b/highwayhash/highwayhash_target.cc
@@ -12,8 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -// WARNING: compiled with different flags => must not define/instantiate any -// inline functions, nor include any headers that do - see instruction_sets.h. +// WARNING: this is a "restricted" source file; avoid including any headers +// unless they are also restricted. See arch_specific.h for details. #include "highwayhash/highwayhash_target.h"
diff --git a/highwayhash/highwayhash_target.h b/highwayhash/highwayhash_target.h index 2d9ed1e..148a882 100644 --- a/highwayhash/highwayhash_target.h +++ b/highwayhash/highwayhash_target.h
@@ -15,12 +15,14 @@ #ifndef HIGHWAYHASH_HIGHWAYHASH_TARGET_H_ #define HIGHWAYHASH_HIGHWAYHASH_TARGET_H_ -// WARNING: compiled with different flags => must not define/instantiate any -// inline functions, nor include any headers that do - see instruction_sets.h. - // Adapter for the InstructionSets::Run dispatcher, which invokes the best // implementations available on the current CPU. +// WARNING: this is a "restricted" header because it is included from +// translation units compiled with different flags. This header and its +// dependencies must not define any function unless it is static inline and/or +// within namespace HH_TARGET_NAME. See arch_specific.h for details. + #include "highwayhash/arch_specific.h" #include "highwayhash/compiler_specific.h" #include "highwayhash/hh_types.h"
diff --git a/highwayhash/highwayhash_test_avx2.cc b/highwayhash/highwayhash_test_avx2.cc index 6bb60b9..f1efe0b 100644 --- a/highwayhash/highwayhash_test_avx2.cc +++ b/highwayhash/highwayhash_test_avx2.cc
@@ -12,5 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +// WARNING: this is a "restricted" source file; avoid including any headers +// unless they are also restricted. See arch_specific.h for details. + #define HH_TARGET_NAME AVX2 #include "highwayhash/highwayhash_test_target.cc"
diff --git a/highwayhash/highwayhash_test_portable.cc b/highwayhash/highwayhash_test_portable.cc index 67213e5..04930a7 100644 --- a/highwayhash/highwayhash_test_portable.cc +++ b/highwayhash/highwayhash_test_portable.cc
@@ -12,5 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +// WARNING: this is a "restricted" source file; avoid including any headers +// unless they are also restricted. See arch_specific.h for details. + #define HH_TARGET_NAME Portable #include "highwayhash/highwayhash_test_target.cc"
diff --git a/highwayhash/highwayhash_test_sse41.cc b/highwayhash/highwayhash_test_sse41.cc index 5e7da27..2d6e83d 100644 --- a/highwayhash/highwayhash_test_sse41.cc +++ b/highwayhash/highwayhash_test_sse41.cc
@@ -12,5 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +// WARNING: this is a "restricted" source file; avoid including any headers +// unless they are also restricted. See arch_specific.h for details. + #define HH_TARGET_NAME SSE41 #include "highwayhash/highwayhash_test_target.cc"
diff --git a/highwayhash/highwayhash_test_target.cc b/highwayhash/highwayhash_test_target.cc index f5d10d5..701c14b 100644 --- a/highwayhash/highwayhash_test_target.cc +++ b/highwayhash/highwayhash_test_target.cc
@@ -12,8 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -// WARNING: compiled with different flags => must not define/instantiate any -// inline functions, nor include any headers that do - see instruction_sets.h. +// WARNING: this is a "restricted" source file; avoid including any headers +// unless they are also restricted. See arch_specific.h for details. #include "highwayhash/highwayhash_test_target.h"
diff --git a/highwayhash/highwayhash_test_target.h b/highwayhash/highwayhash_test_target.h index 78f6d36..b89695d 100644 --- a/highwayhash/highwayhash_test_target.h +++ b/highwayhash/highwayhash_test_target.h
@@ -18,8 +18,10 @@ // Tests called by InstructionSets::RunAll, so we can verify all // implementations supported by the current CPU. -// WARNING: compiled with different flags => must not define/instantiate any -// inline functions, nor include any headers that do - see instruction_sets.h. +// WARNING: this is a "restricted" header because it is included from +// translation units compiled with different flags. This header and its +// dependencies must not define any function unless it is static inline and/or +// within namespace HH_TARGET_NAME. See arch_specific.h for details. #include <stddef.h>
diff --git a/highwayhash/iaca.h b/highwayhash/iaca.h index dbe2212..7196a2a 100644 --- a/highwayhash/iaca.h +++ b/highwayhash/iaca.h
@@ -15,8 +15,10 @@ #ifndef HIGHWAYHASH_IACA_H_ #define HIGHWAYHASH_IACA_H_ -// WARNING: compiled with different flags => must not define/instantiate any -// inline functions, nor include any headers that do - see instruction_sets.h. +// WARNING: this is a "restricted" header because it is included from +// translation units compiled with different flags. This header and its +// dependencies must not define any function unless it is static inline and/or +// within namespace HH_TARGET_NAME. See arch_specific.h for details. #include "highwayhash/compiler_specific.h" @@ -33,7 +35,7 @@ namespace highwayhash { // Call before the region of interest. Fences hopefully prevent reordering. -HH_INLINE void BeginIACA() { +static HH_INLINE void BeginIACA() { #if HH_ENABLE_IACA && (HH_GCC_VERSION || HH_CLANG_VERSION) HH_COMPILER_FENCE; asm volatile( @@ -45,7 +47,7 @@ } // Call after the region of interest. Fences hopefully prevent reordering. -HH_INLINE void EndIACA() { +static HH_INLINE void EndIACA() { #if HH_ENABLE_IACA && (HH_GCC_VERSION || HH_CLANG_VERSION) HH_COMPILER_FENCE; asm volatile(
diff --git a/highwayhash/load3.h b/highwayhash/load3.h index 3ff1bbd..68221e6 100644 --- a/highwayhash/load3.h +++ b/highwayhash/load3.h
@@ -15,8 +15,10 @@ #ifndef HIGHWAYHASH_HH_LOAD3_H_ #define HIGHWAYHASH_HH_LOAD3_H_ -// WARNING: compiled with different flags => must not define/instantiate any -// inline functions, nor include any headers that do - see instruction_sets.h. +// WARNING: this is a "restricted" header because it is included from +// translation units compiled with different flags. This header and its +// dependencies must not define any function unless it is static inline and/or +// within namespace HH_TARGET_NAME. See arch_specific.h for details. #include <stddef.h> #include <stdint.h>
diff --git a/highwayhash/nanobenchmark.h b/highwayhash/nanobenchmark.h index ecd51d5..1cf6426 100644 --- a/highwayhash/nanobenchmark.h +++ b/highwayhash/nanobenchmark.h
@@ -69,8 +69,10 @@ // central tendency of the measurement samples with the "half sample mode", // which is more robust to outliers and skewed data than the mean or median. -// WARNING: compiled with different flags => must not define/instantiate any -// inline functions, nor include any headers that do - see instruction_sets.h. +// WARNING: this is a "restricted" header because it is included from +// translation units compiled with different flags. This header and its +// dependencies must not define any function unless it is static inline and/or +// within namespace HH_TARGET_NAME. See arch_specific.h for details. #include <stddef.h> #include <stdint.h>
diff --git a/highwayhash/scalar.h b/highwayhash/scalar.h index 05705eb..72ccae7 100644 --- a/highwayhash/scalar.h +++ b/highwayhash/scalar.h
@@ -15,6 +15,11 @@ #ifndef HIGHWAYHASH_SCALAR_H_ #define HIGHWAYHASH_SCALAR_H_ +// WARNING: this is a "restricted" header because it is included from +// translation units compiled with different flags. This header and its +// dependencies must not define any function unless it is static inline and/or +// within namespace HH_TARGET_NAME. See arch_specific.h for details. + #include <stddef.h> // size_t #include <stdint.h>
diff --git a/highwayhash/vector128.h b/highwayhash/vector128.h index 2c22925..53eb9f1 100644 --- a/highwayhash/vector128.h +++ b/highwayhash/vector128.h
@@ -25,8 +25,10 @@ // number of bits per lane and T is the lane type: unsigned integer (U), // signed integer (I), or floating-point (F). -// WARNING: compiled with different flags => must not define/instantiate any -// inline functions, nor include any headers that do - see instruction_sets.h. +// WARNING: this is a "restricted" header because it is included from +// translation units compiled with different flags. This header and its +// dependencies must not define any function unless it is static inline and/or +// within namespace HH_TARGET_NAME. See arch_specific.h for details. #include <stddef.h> #include <stdint.h>
diff --git a/highwayhash/vector256.h b/highwayhash/vector256.h index c508816..d1ccec4 100644 --- a/highwayhash/vector256.h +++ b/highwayhash/vector256.h
@@ -25,8 +25,10 @@ // number of bits per lane and T is the lane type: unsigned integer (U), // signed integer (I), or floating-point (F). -// WARNING: compiled with different flags => must not define/instantiate any -// inline functions, nor include any headers that do - see instruction_sets.h. +// WARNING: this is a "restricted" header because it is included from +// translation units compiled with different flags. This header and its +// dependencies must not define any function unless it is static inline and/or +// within namespace HH_TARGET_NAME. See arch_specific.h for details. #include <stddef.h> #include <stdint.h>
diff --git a/highwayhash/vector_test_avx2.cc b/highwayhash/vector_test_avx2.cc index e5bdb33..30ce2c9 100644 --- a/highwayhash/vector_test_avx2.cc +++ b/highwayhash/vector_test_avx2.cc
@@ -12,5 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +// WARNING: this is a "restricted" source file; avoid including any headers +// unless they are also restricted. See arch_specific.h for details. + #define HH_TARGET_NAME AVX2 #include "highwayhash/vector_test_target.cc"
diff --git a/highwayhash/vector_test_portable.cc b/highwayhash/vector_test_portable.cc index 638f69d..a742b4b 100644 --- a/highwayhash/vector_test_portable.cc +++ b/highwayhash/vector_test_portable.cc
@@ -12,5 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +// WARNING: this is a "restricted" source file; avoid including any headers +// unless they are also restricted. See arch_specific.h for details. + #define HH_TARGET_NAME Portable #include "highwayhash/vector_test_target.cc"
diff --git a/highwayhash/vector_test_sse41.cc b/highwayhash/vector_test_sse41.cc index 9addaff..80e11b5 100644 --- a/highwayhash/vector_test_sse41.cc +++ b/highwayhash/vector_test_sse41.cc
@@ -12,5 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +// WARNING: this is a "restricted" source file; avoid including any headers +// unless they are also restricted. See arch_specific.h for details. + #define HH_TARGET_NAME SSE41 #include "highwayhash/vector_test_target.cc"
diff --git a/highwayhash/vector_test_target.cc b/highwayhash/vector_test_target.cc index c9371de..26664f4 100644 --- a/highwayhash/vector_test_target.cc +++ b/highwayhash/vector_test_target.cc
@@ -12,14 +12,11 @@ // See the License for the specific language governing permissions and // limitations under the License. -// WARNING: compiled with different flags => must not define/instantiate any -// inline functions, nor include any headers that do - see instruction_sets.h. +// WARNING: this is a "restricted" source file; avoid including any headers +// unless they are also restricted. See arch_specific.h for details. #include "highwayhash/vector_test_target.h" -#include <algorithm> -#include <limits> - #include "highwayhash/arch_specific.h" #if HH_TARGET == HH_TARGET_AVX2 @@ -68,6 +65,26 @@ } } +// MaxValue<T>()() replaces std::numeric_limits<T>::max(). +template <typename T> +struct MaxValue; +template <> +struct MaxValue<uint8_t> { + constexpr uint8_t operator()() { return 0xFFu; } +}; +template <> +struct MaxValue<uint16_t> { + constexpr uint16_t operator()() { return 0xFFFFu; } +}; +template <> +struct MaxValue<uint32_t> { + constexpr uint32_t operator()() { return 0xFFFFFFFFu; } +}; +template <> +struct MaxValue<uint64_t> { + constexpr uint64_t operator()() { return 0xFFFFFFFFFFFFFFFFull; } +}; + template <typename T> void TestMembersAndBinaryOperatorsExceptShifts(const HHNotify notify) { // uninitialized @@ -85,7 +102,7 @@ // equal const V<T> veq(v3 == v3b); - NotifyIfUnequal(veq, std::numeric_limits<T>::max(), notify); + NotifyIfUnequal(veq, MaxValue<T>()(), notify); // Copying to, and constructing from intrinsic yields same result. typename V<T>::Intrinsic nv2 = v2; @@ -125,7 +142,7 @@ // Sign bit constexpr int kSign = (sizeof(T) * 8) - 1; - constexpr T max = std::numeric_limits<T>::max(); + constexpr T max = MaxValue<T>()(); constexpr T sign = ~(max >> 1); NotifyIfUnequal(v1 << kSign, sign, notify); @@ -137,8 +154,12 @@ void TestLoadStore(const HHNotify notify) { const size_t n = V<T>::N; T lanes[2 * n] HH_ALIGNAS(32); - std::fill(lanes, lanes + n, 4); - std::fill(lanes + n, lanes + 2 * n, 5); + for (size_t i = 0; i < n; ++i) { + lanes[i] = 4; + } + for (size_t i = n; i < 2 * n; ++i) { + lanes[i] = 5; + } // Aligned load const V<T> v4 = Load<V<T>>(lanes); NotifyIfUnequal(v4, T(4), notify);
diff --git a/highwayhash/vector_test_target.h b/highwayhash/vector_test_target.h index f9310d4..f1ff638 100644 --- a/highwayhash/vector_test_target.h +++ b/highwayhash/vector_test_target.h
@@ -15,8 +15,10 @@ #ifndef HIGHWAYHASH_VECTOR_TEST_TARGET_H_ #define HIGHWAYHASH_VECTOR_TEST_TARGET_H_ -// WARNING: compiled with different flags => must not define/instantiate any -// inline functions, nor include any headers that do - see instruction_sets.h. +// WARNING: this is a "restricted" header because it is included from +// translation units compiled with different flags. This header and its +// dependencies must not define any function unless it is static inline and/or +// within namespace HH_TARGET_NAME. See arch_specific.h for details. #include "highwayhash/arch_specific.h" #include "highwayhash/hh_types.h"