When building abseil-cpp bin/absl_hash_test with Clang in -fno-pic
mode, an instruction like movl $foo-2147483648, $eax may be produced
(subtracting a number from the address of a static variable). If foo's
address is smaller than 2147483648, GNU ld/gold/LLD will error because
R_X86_64_32 cannot represent a negative value.
using absl::Hash; struct NoOp { template < typename HashCode > friend HashCode AbslHashValue(HashCode , NoOp ); }; template <typename> class HashIntTest : public testing::Test {}; TYPED_TEST_SUITE_P(HashIntTest); TYPED_TEST_P(HashIntTest, BasicUsage) { if (std::numeric_limits< TypeParam >::min ) EXPECT_NE(Hash< NoOp >()({}), Hash< TypeParam >()(std::numeric_limits< TypeParam >::min())); } REGISTER_TYPED_TEST_CASE_P(HashIntTest, BasicUsage); using IntTypes = testing::Types< int32_t>; INSTANTIATE_TYPED_TEST_CASE_P(My, HashIntTest, IntTypes); ld: error: hash_test.cc:(function (anonymous namespace)::gtest_suite_HashIntTest_::BasicUsage<int>::TestBody(): .text+0x4E472): relocation R_X86_64_32 out of range: 18446744071564237392 is not in [0, 4294967295]; references absl::hash_internal::HashState::kSeed
Actually any negative offset is not allowed because the symbol address
can be zero (e.g. set by -Wl,--defsym=foo=0). So disallow such folding.
Maybe just need to add Offset >=0 && here?