From 226d9d8c24b889c02ceffd1c574ad554657f1d70 Mon Sep 17 00:00:00 2001 From: Victor Zverovich Date: Wed, 15 Sep 2021 16:01:46 -0700 Subject: [PATCH] Remove compiler/ast/endianness.h Summary: Remove `compiler/ast/endianness.h` because it has nothing to do with AST and only used in two places. Replace its uses with conditionally compiled calls to `__builtin_bswap64`. Another option is to move `endianness.h` outside of AST but it's probably an overkill considering that there are only two uses, three lines of code each. While at it fix UBs due to invalid type conversion. Reviewed By: Mizuchi Differential Revision: D30883166 fbshipit-source-id: 024b0c09454057b732a36baa024e1de77fc8535c --- thrift/compiler/ast/endianness.h | 53 ------------------- thrift/compiler/ast/t_type.cc | 21 +++----- .../compiler/generate/t_concat_generator.cc | 18 +++---- 3 files changed, 16 insertions(+), 76 deletions(-) delete mode 100644 thrift/compiler/ast/endianness.h diff --git a/thrift/compiler/ast/endianness.h b/thrift/compiler/ast/endianness.h deleted file mode 100644 index 11a35257fc4..00000000000 --- a/thrift/compiler/ast/endianness.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include - -namespace apache { -namespace thrift { -namespace compiler { - -inline constexpr bool kIsBigEndian() { -#ifdef _WIN32 - return false; -#else - return __BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__; -#endif -} - -/* - * Use system specific byte swap functions - */ -inline uint64_t bswap(const uint64_t b) { -#ifdef _WIN32 - return _byteswap_uint64(b); -#else - return __builtin_bswap64(b); -#endif -} - -/* - * Convert a number from any platform to little Endian form. - */ -inline uint64_t bswap_host_to_little_endian(const uint64_t b) { - return kIsBigEndian() ? bswap(b) : b; -} - -} // namespace compiler -} // namespace thrift -} // namespace apache diff --git a/thrift/compiler/ast/t_type.cc b/thrift/compiler/ast/t_type.cc index c17088593b2..5baeb2798e9 100644 --- a/thrift/compiler/ast/t_type.cc +++ b/thrift/compiler/ast/t_type.cc @@ -23,7 +23,6 @@ #include -#include #include #include @@ -60,19 +59,15 @@ const std::string& t_type::type_name(type t) { } uint64_t t_type::get_type_id() const { - // This union allows the conversion of the SHA char buffer to a 64bit uint - union { - uint64_t val; - unsigned char buf[SHA_DIGEST_LENGTH]; - } u; - std::string name = get_full_name(); - SHA1(reinterpret_cast(name.data()), name.size(), u.buf); - const auto hash = - apache::thrift::compiler::bswap_host_to_little_endian(u.val); - type tv = get_type_value(); - - return (hash & ~t_type::kTypeMask) | int(tv); + unsigned char buf[SHA_DIGEST_LENGTH] = {}; + SHA1(reinterpret_cast(name.data()), name.size(), buf); + uint64_t hash = 0; + std::memcpy(&hash, &buf, sizeof(hash)); +#if !defined(_WIN32) && __BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__ + hash = __builtin_bswap64(hash); +#endif + return (hash & ~t_type::kTypeMask) | static_cast(get_type_value()); } std::string t_type::get_scoped_name() const { diff --git a/thrift/compiler/generate/t_concat_generator.cc b/thrift/compiler/generate/t_concat_generator.cc index 217328d5a09..9f2b1521f5d 100644 --- a/thrift/compiler/generate/t_concat_generator.cc +++ b/thrift/compiler/generate/t_concat_generator.cc @@ -22,8 +22,6 @@ #include -#include - #include using namespace std; @@ -152,17 +150,17 @@ std::string t_concat_generator::generate_structural_id( std::string hashable_keys_list = ss.str(); // Hash the string and generate a portable hash number. - union { - uint64_t val; - unsigned char buf[SHA_DIGEST_LENGTH]; - } u; + unsigned char buf[SHA_DIGEST_LENGTH] = {}; SHA1( reinterpret_cast(hashable_keys_list.data()), hashable_keys_list.size(), - u.buf); - const uint64_t hash = - (apache::thrift::compiler::bswap_host_to_little_endian(u.val) & - 0x7FFFFFFFFFFFFFFFull); // 63 bits + buf); + uint64_t hash = 0; + std::memcpy(&hash, &buf, sizeof(hash)); +#if !defined(_WIN32) && __BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__ + hash = __builtin_bswap64(hash); +#endif + hash &= 0x7FFFFFFFFFFFFFFFull; // 63 bits // Generate a readable number. char structural_id[21];