summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--base/BUILD.gn1
-rw-r--r--base/base.gypi1
-rw-r--r--base/bit_cast.h71
-rw-r--r--base/macros.h65
-rw-r--r--base/time/time_win.cc1
-rw-r--r--chrome/browser/profile_resetter/triggered_profile_resetter_win_unittest.cc1
-rw-r--r--chromeos/hugepage_text/hugepage_text.cc1
-rw-r--r--components/compression/compression_utils.cc1
-rw-r--r--components/visitedlink/common/visitedlink_common.cc1
-rw-r--r--components/webcrypto/algorithms/rsa_oaep.cc1
-rw-r--r--content/renderer/pepper/pepper_plugin_instance_impl.cc1
-rw-r--r--courgette/difference_estimator.cc1
-rw-r--r--gpu/command_buffer/tests/gl_readback_unittest.cc1
-rw-r--r--media/cdm/ppapi/ppapi_cdm_adapter.cc2
-rw-r--r--net/disk_cache/blockfile/bitmap.h1
-rw-r--r--net/disk_cache/blockfile/disk_format_v3.h1
-rw-r--r--net/disk_cache/blockfile/index_table_v3.cc1
-rw-r--r--net/filter/brotli_filter.cc1
-rw-r--r--net/filter/gzip_filter.cc1
-rw-r--r--net/filter/gzip_filter_unittest.cc1
-rw-r--r--net/filter/sdch_filter_unittest.cc1
-rw-r--r--net/quic/test_tools/mock_random.cc2
-rw-r--r--pdf/out_of_process_instance.h1
-rw-r--r--ppapi/shared_impl/ppb_view_shared.cc2
-rw-r--r--remoting/client/plugin/pepper_util.cc1
-rw-r--r--sandbox/win/src/Wow64.cc1
-rw-r--r--sandbox/win/src/service_resolver_32.cc1
-rw-r--r--sandbox/win/src/service_resolver_unittest.cc1
-rw-r--r--sandbox/win/wow_helper/service64_resolver.cc1
-rw-r--r--sync/internal_api/http_bridge.cc1
-rw-r--r--sync/internal_api/http_bridge_unittest.cc1
-rw-r--r--third_party/crashpad/README.chromium2
-rw-r--r--third_party/crashpad/crashpad/util/numeric/int128_test.cc5
33 files changed, 108 insertions, 67 deletions
diff --git a/base/BUILD.gn b/base/BUILD.gn
index 589af08..5d8510f 100644
--- a/base/BUILD.gn
+++ b/base/BUILD.gn
@@ -213,6 +213,7 @@ component("base") {
"bind_helpers.h",
"bind_internal.h",
"bind_internal_win.h",
+ "bit_cast.h",
"bits.h",
"build_time.cc",
"build_time.h",
diff --git a/base/base.gypi b/base/base.gypi
index 5e90823..bb028bd 100644
--- a/base/base.gypi
+++ b/base/base.gypi
@@ -120,6 +120,7 @@
'bind_helpers.h',
'bind_internal.h',
'bind_internal_win.h',
+ 'bit_cast.h',
'bits.h',
'build_time.cc',
'build_time.h',
diff --git a/base/bit_cast.h b/base/bit_cast.h
new file mode 100644
index 0000000..b548467
--- /dev/null
+++ b/base/bit_cast.h
@@ -0,0 +1,71 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef BASE_BIT_CAST_H_
+#define BASE_BIT_CAST_H_
+
+#include <string.h>
+
+// bit_cast<Dest,Source> is a template function that implements the equivalent
+// of "*reinterpret_cast<Dest*>(&source)". We need this in very low-level
+// functions like the protobuf library and fast math support.
+//
+// float f = 3.14159265358979;
+// int i = bit_cast<int32_t>(f);
+// // i = 0x40490fdb
+//
+// The classical address-casting method is:
+//
+// // WRONG
+// float f = 3.14159265358979; // WRONG
+// int i = * reinterpret_cast<int*>(&f); // WRONG
+//
+// The address-casting method actually produces undefined behavior according to
+// the ISO C++98 specification, section 3.10 ("basic.lval"), paragraph 15.
+// (This did not substantially change in C++11.) Roughly, this section says: if
+// an object in memory has one type, and a program accesses it with a different
+// type, then the result is undefined behavior for most values of "different
+// type".
+//
+// This is true for any cast syntax, either *(int*)&f or
+// *reinterpret_cast<int*>(&f). And it is particularly true for conversions
+// between integral lvalues and floating-point lvalues.
+//
+// The purpose of this paragraph is to allow optimizing compilers to assume that
+// expressions with different types refer to different memory. Compilers are
+// known to take advantage of this. So a non-conforming program quietly
+// produces wildly incorrect output.
+//
+// The problem is not the use of reinterpret_cast. The problem is type punning:
+// holding an object in memory of one type and reading its bits back using a
+// different type.
+//
+// The C++ standard is more subtle and complex than this, but that is the basic
+// idea.
+//
+// Anyways ...
+//
+// bit_cast<> calls memcpy() which is blessed by the standard, especially by the
+// example in section 3.9 . Also, of course, bit_cast<> wraps up the nasty
+// logic in one place.
+//
+// Fortunately memcpy() is very fast. In optimized mode, compilers replace
+// calls to memcpy() with inline object code when the size argument is a
+// compile-time constant. On a 32-bit system, memcpy(d,s,4) compiles to one
+// load and one store, and memcpy(d,s,8) compiles to two loads and two stores.
+//
+// WARNING: if Dest or Source is a non-POD type, the result of the memcpy
+// is likely to surprise you.
+
+template <class Dest, class Source>
+inline Dest bit_cast(const Source& source) {
+ static_assert(sizeof(Dest) == sizeof(Source),
+ "bit_cast requires source and destination to be the same size");
+
+ Dest dest;
+ memcpy(&dest, &source, sizeof(dest));
+ return dest;
+}
+
+#endif // BASE_BIT_CAST_H_
diff --git a/base/macros.h b/base/macros.h
index fa12dd2..46ee1da 100644
--- a/base/macros.h
+++ b/base/macros.h
@@ -11,7 +11,6 @@
#define BASE_MACROS_H_
#include <stddef.h> // For size_t.
-#include <string.h> // For memcpy.
// Put this in the declarations for a class to be uncopyable.
#define DISALLOW_COPY(TypeName) \
@@ -49,70 +48,6 @@
template <typename T, size_t N> char (&ArraySizeHelper(T (&array)[N]))[N];
#define arraysize(array) (sizeof(ArraySizeHelper(array)))
-// bit_cast<Dest,Source> is a template function that implements the
-// equivalent of "*reinterpret_cast<Dest*>(&source)". We need this in
-// very low-level functions like the protobuf library and fast math
-// support.
-//
-// float f = 3.14159265358979;
-// int i = bit_cast<int32_t>(f);
-// // i = 0x40490fdb
-//
-// The classical address-casting method is:
-//
-// // WRONG
-// float f = 3.14159265358979; // WRONG
-// int i = * reinterpret_cast<int*>(&f); // WRONG
-//
-// The address-casting method actually produces undefined behavior
-// according to ISO C++ specification section 3.10 -15 -. Roughly, this
-// section says: if an object in memory has one type, and a program
-// accesses it with a different type, then the result is undefined
-// behavior for most values of "different type".
-//
-// This is true for any cast syntax, either *(int*)&f or
-// *reinterpret_cast<int*>(&f). And it is particularly true for
-// conversions between integral lvalues and floating-point lvalues.
-//
-// The purpose of 3.10 -15- is to allow optimizing compilers to assume
-// that expressions with different types refer to different memory. gcc
-// 4.0.1 has an optimizer that takes advantage of this. So a
-// non-conforming program quietly produces wildly incorrect output.
-//
-// The problem is not the use of reinterpret_cast. The problem is type
-// punning: holding an object in memory of one type and reading its bits
-// back using a different type.
-//
-// The C++ standard is more subtle and complex than this, but that
-// is the basic idea.
-//
-// Anyways ...
-//
-// bit_cast<> calls memcpy() which is blessed by the standard,
-// especially by the example in section 3.9 . Also, of course,
-// bit_cast<> wraps up the nasty logic in one place.
-//
-// Fortunately memcpy() is very fast. In optimized mode, with a
-// constant size, gcc 2.95.3, gcc 4.0.1, and msvc 7.1 produce inline
-// code with the minimal amount of data movement. On a 32-bit system,
-// memcpy(d,s,4) compiles to one load and one store, and memcpy(d,s,8)
-// compiles to two loads and two stores.
-//
-// I tested this code with gcc 2.95.3, gcc 4.0.1, icc 8.1, and msvc 7.1.
-//
-// WARNING: if Dest or Source is a non-POD type, the result of the memcpy
-// is likely to surprise you.
-
-template <class Dest, class Source>
-inline Dest bit_cast(const Source& source) {
- static_assert(sizeof(Dest) == sizeof(Source),
- "bit_cast requires source and destination to be the same size");
-
- Dest dest;
- memcpy(&dest, &source, sizeof(dest));
- return dest;
-}
-
// Used to explicitly mark the return value of a function as unused. If you are
// really sure you don't want to do anything with the return value of a function
// that has been marked WARN_UNUSED_RESULT, wrap it with this. Example:
diff --git a/base/time/time_win.cc b/base/time/time_win.cc
index b2d9c76..dc968ad 100644
--- a/base/time/time_win.cc
+++ b/base/time/time_win.cc
@@ -38,6 +38,7 @@
#include <mmsystem.h>
#include <stdint.h>
+#include "base/bit_cast.h"
#include "base/cpu.h"
#include "base/lazy_instance.h"
#include "base/logging.h"
diff --git a/chrome/browser/profile_resetter/triggered_profile_resetter_win_unittest.cc b/chrome/browser/profile_resetter/triggered_profile_resetter_win_unittest.cc
index 1db72be..565f1b4 100644
--- a/chrome/browser/profile_resetter/triggered_profile_resetter_win_unittest.cc
+++ b/chrome/browser/profile_resetter/triggered_profile_resetter_win_unittest.cc
@@ -6,6 +6,7 @@
#include <stdint.h>
+#include "base/bit_cast.h"
#include "base/memory/scoped_ptr.h"
#include "base/metrics/field_trial.h"
#include "base/prefs/pref_service.h"
diff --git a/chromeos/hugepage_text/hugepage_text.cc b/chromeos/hugepage_text/hugepage_text.cc
index a14a2d1..ccae53f 100644
--- a/chromeos/hugepage_text/hugepage_text.cc
+++ b/chromeos/hugepage_text/hugepage_text.cc
@@ -10,6 +10,7 @@
#include <link.h>
#include <sys/mman.h>
+#include "base/bit_cast.h"
#include "base/logging.h"
namespace chromeos {
diff --git a/components/compression/compression_utils.cc b/components/compression/compression_utils.cc
index dfc1664..aedfc8e 100644
--- a/components/compression/compression_utils.cc
+++ b/components/compression/compression_utils.cc
@@ -10,6 +10,7 @@
#include <vector>
+#include "base/bit_cast.h"
#include "base/logging.h"
#include "base/sys_byteorder.h"
#include "third_party/zlib/zlib.h"
diff --git a/components/visitedlink/common/visitedlink_common.cc b/components/visitedlink/common/visitedlink_common.cc
index b052142..1703cac 100644
--- a/components/visitedlink/common/visitedlink_common.cc
+++ b/components/visitedlink/common/visitedlink_common.cc
@@ -6,6 +6,7 @@
#include <string.h> // for memset()
+#include "base/bit_cast.h"
#include "base/logging.h"
#include "base/md5.h"
#include "url/gurl.h"
diff --git a/components/webcrypto/algorithms/rsa_oaep.cc b/components/webcrypto/algorithms/rsa_oaep.cc
index 8e4452e..27e834b 100644
--- a/components/webcrypto/algorithms/rsa_oaep.cc
+++ b/components/webcrypto/algorithms/rsa_oaep.cc
@@ -5,6 +5,7 @@
#include <openssl/evp.h>
#include <stddef.h>
#include <stdint.h>
+#include <string.h>
#include "components/webcrypto/algorithms/rsa.h"
#include "components/webcrypto/algorithms/util.h"
diff --git a/content/renderer/pepper/pepper_plugin_instance_impl.cc b/content/renderer/pepper/pepper_plugin_instance_impl.cc
index 172c3b7..de1cdaf 100644
--- a/content/renderer/pepper/pepper_plugin_instance_impl.cc
+++ b/content/renderer/pepper/pepper_plugin_instance_impl.cc
@@ -7,6 +7,7 @@
#include <utility>
#include "base/bind.h"
+#include "base/bit_cast.h"
#include "base/callback_helpers.h"
#include "base/location.h"
#include "base/logging.h"
diff --git a/courgette/difference_estimator.cc b/courgette/difference_estimator.cc
index 8b7aa29..ac9f0d4 100644
--- a/courgette/difference_estimator.cc
+++ b/courgette/difference_estimator.cc
@@ -10,6 +10,7 @@
#include <stddef.h>
#include <stdint.h>
+#include <string.h>
#include "base/containers/hash_tables.h"
#include "base/macros.h"
diff --git a/gpu/command_buffer/tests/gl_readback_unittest.cc b/gpu/command_buffer/tests/gl_readback_unittest.cc
index d629564..eaaa1bb 100644
--- a/gpu/command_buffer/tests/gl_readback_unittest.cc
+++ b/gpu/command_buffer/tests/gl_readback_unittest.cc
@@ -11,6 +11,7 @@
#include <cmath>
#include "base/bind.h"
+#include "base/bit_cast.h"
#include "base/location.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
diff --git a/media/cdm/ppapi/ppapi_cdm_adapter.cc b/media/cdm/ppapi/ppapi_cdm_adapter.cc
index 40b0bae..d3a143a 100644
--- a/media/cdm/ppapi/ppapi_cdm_adapter.cc
+++ b/media/cdm/ppapi/ppapi_cdm_adapter.cc
@@ -4,6 +4,8 @@
#include "media/cdm/ppapi/ppapi_cdm_adapter.h"
+#include <string.h>
+
#include "base/macros.h"
#include "build/build_config.h"
#include "media/base/limits.h"
diff --git a/net/disk_cache/blockfile/bitmap.h b/net/disk_cache/blockfile/bitmap.h
index 54e4162..59a987a 100644
--- a/net/disk_cache/blockfile/bitmap.h
+++ b/net/disk_cache/blockfile/bitmap.h
@@ -6,6 +6,7 @@
#define NET_DISK_CACHE_BLOCKFILE_BITMAP_H_
#include <stdint.h>
+#include <string.h>
#include "base/macros.h"
#include "net/base/net_export.h"
diff --git a/net/disk_cache/blockfile/disk_format_v3.h b/net/disk_cache/blockfile/disk_format_v3.h
index 3ec43e8..da873ed 100644
--- a/net/disk_cache/blockfile/disk_format_v3.h
+++ b/net/disk_cache/blockfile/disk_format_v3.h
@@ -46,6 +46,7 @@
#define NET_DISK_CACHE_BLOCKFILE_DISK_FORMAT_V3_H_
#include <stdint.h>
+#include <string.h>
#include "net/disk_cache/blockfile/disk_format_base.h"
diff --git a/net/disk_cache/blockfile/index_table_v3.cc b/net/disk_cache/blockfile/index_table_v3.cc
index 426d683..9c24e80 100644
--- a/net/disk_cache/blockfile/index_table_v3.cc
+++ b/net/disk_cache/blockfile/index_table_v3.cc
@@ -9,6 +9,7 @@
#include <set>
#include <utility>
+#include "base/bit_cast.h"
#include "base/bits.h"
#include "net/base/io_buffer.h"
#include "net/base/net_errors.h"
diff --git a/net/filter/brotli_filter.cc b/net/filter/brotli_filter.cc
index 66e778a..939a6f7 100644
--- a/net/filter/brotli_filter.cc
+++ b/net/filter/brotli_filter.cc
@@ -4,6 +4,7 @@
#include "net/filter/brotli_filter.h"
+#include "base/bit_cast.h"
#include "base/macros.h"
#include "base/numerics/safe_conversions.h"
#include "base/numerics/safe_math.h"
diff --git a/net/filter/gzip_filter.cc b/net/filter/gzip_filter.cc
index 6d15ee9..209e3c4 100644
--- a/net/filter/gzip_filter.cc
+++ b/net/filter/gzip_filter.cc
@@ -4,6 +4,7 @@
#include "net/filter/gzip_filter.h"
+#include "base/bit_cast.h"
#include "base/logging.h"
#include "net/filter/gzip_header.h"
#include "third_party/zlib/zlib.h"
diff --git a/net/filter/gzip_filter_unittest.cc b/net/filter/gzip_filter_unittest.cc
index 2f11e28a..e25cc1c 100644
--- a/net/filter/gzip_filter_unittest.cc
+++ b/net/filter/gzip_filter_unittest.cc
@@ -5,6 +5,7 @@
#include <fstream>
#include <ostream>
+#include "base/bit_cast.h"
#include "base/files/file_util.h"
#include "base/memory/scoped_ptr.h"
#include "base/path_service.h"
diff --git a/net/filter/sdch_filter_unittest.cc b/net/filter/sdch_filter_unittest.cc
index cbb85a8..701aba0 100644
--- a/net/filter/sdch_filter_unittest.cc
+++ b/net/filter/sdch_filter_unittest.cc
@@ -8,6 +8,7 @@
#include <string>
#include <vector>
+#include "base/bit_cast.h"
#include "base/logging.h"
#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
diff --git a/net/quic/test_tools/mock_random.cc b/net/quic/test_tools/mock_random.cc
index 87977be..f1bc024 100644
--- a/net/quic/test_tools/mock_random.cc
+++ b/net/quic/test_tools/mock_random.cc
@@ -4,6 +4,8 @@
#include "net/quic/test_tools/mock_random.h"
+#include <string.h>
+
namespace net {
namespace test {
diff --git a/pdf/out_of_process_instance.h b/pdf/out_of_process_instance.h
index f210d0a5..bdd0e68 100644
--- a/pdf/out_of_process_instance.h
+++ b/pdf/out_of_process_instance.h
@@ -6,6 +6,7 @@
#define PDF_OUT_OF_PROCESS_INSTANCE_H_
#include <stdint.h>
+#include <string.h>
#include <queue>
#include <set>
diff --git a/ppapi/shared_impl/ppb_view_shared.cc b/ppapi/shared_impl/ppb_view_shared.cc
index 36c047d..5c1ab97 100644
--- a/ppapi/shared_impl/ppb_view_shared.cc
+++ b/ppapi/shared_impl/ppb_view_shared.cc
@@ -4,6 +4,8 @@
#include "ppapi/shared_impl/ppb_view_shared.h"
+#include <string.h>
+
namespace {
bool IsRectNonempty(const PP_Rect& rect) {
diff --git a/remoting/client/plugin/pepper_util.cc b/remoting/client/plugin/pepper_util.cc
index 0e575c8..0315382 100644
--- a/remoting/client/plugin/pepper_util.cc
+++ b/remoting/client/plugin/pepper_util.cc
@@ -4,6 +4,7 @@
#include "remoting/client/plugin/pepper_util.h"
+#include "base/bit_cast.h"
#include "base/callback.h"
#include "base/logging.h"
#include "base/sys_byteorder.h"
diff --git a/sandbox/win/src/Wow64.cc b/sandbox/win/src/Wow64.cc
index d07d72f..c5984d6 100644
--- a/sandbox/win/src/Wow64.cc
+++ b/sandbox/win/src/Wow64.cc
@@ -8,6 +8,7 @@
#include <sstream>
+#include "base/bit_cast.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "base/win/scoped_process_information.h"
diff --git a/sandbox/win/src/service_resolver_32.cc b/sandbox/win/src/service_resolver_32.cc
index 4fc96d3..f809227 100644
--- a/sandbox/win/src/service_resolver_32.cc
+++ b/sandbox/win/src/service_resolver_32.cc
@@ -6,6 +6,7 @@
#include <stddef.h>
+#include "base/bit_cast.h"
#include "base/memory/scoped_ptr.h"
#include "sandbox/win/src/win_utils.h"
diff --git a/sandbox/win/src/service_resolver_unittest.cc b/sandbox/win/src/service_resolver_unittest.cc
index 421b814..25d0875 100644
--- a/sandbox/win/src/service_resolver_unittest.cc
+++ b/sandbox/win/src/service_resolver_unittest.cc
@@ -6,6 +6,7 @@
#include <stddef.h>
+#include "base/bit_cast.h"
#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/win/windows_version.h"
diff --git a/sandbox/win/wow_helper/service64_resolver.cc b/sandbox/win/wow_helper/service64_resolver.cc
index b5b67cc..0424d9f 100644
--- a/sandbox/win/wow_helper/service64_resolver.cc
+++ b/sandbox/win/wow_helper/service64_resolver.cc
@@ -7,6 +7,7 @@
#include <limits.h>
#include <stddef.h>
+#include "base/bit_cast.h"
#include "base/memory/scoped_ptr.h"
#include "sandbox/win/wow_helper/target_code.h"
diff --git a/sync/internal_api/http_bridge.cc b/sync/internal_api/http_bridge.cc
index b8d57cc..b02ede8 100644
--- a/sync/internal_api/http_bridge.cc
+++ b/sync/internal_api/http_bridge.cc
@@ -9,6 +9,7 @@
#include <vector>
+#include "base/bit_cast.h"
#include "base/message_loop/message_loop.h"
#include "base/metrics/field_trial.h"
#include "base/metrics/histogram_macros.h"
diff --git a/sync/internal_api/http_bridge_unittest.cc b/sync/internal_api/http_bridge_unittest.cc
index d61f644..206adcb 100644
--- a/sync/internal_api/http_bridge_unittest.cc
+++ b/sync/internal_api/http_bridge_unittest.cc
@@ -5,6 +5,7 @@
#include <stddef.h>
#include <stdint.h>
+#include "base/bit_cast.h"
#include "base/metrics/field_trial.h"
#include "base/strings/stringprintf.h"
#include "base/synchronization/waitable_event.h"
diff --git a/third_party/crashpad/README.chromium b/third_party/crashpad/README.chromium
index 9ada866..92bdd99 100644
--- a/third_party/crashpad/README.chromium
+++ b/third_party/crashpad/README.chromium
@@ -35,4 +35,4 @@ $ cd "${CRASHPAD_DIR}"
$ git am --3way --message-id -p4 /tmp/patchdir
Local Modifications:
-None.
+- Move bit_cast from base/macros.h to its own header.
diff --git a/third_party/crashpad/crashpad/util/numeric/int128_test.cc b/third_party/crashpad/crashpad/util/numeric/int128_test.cc
index c0ad74e..61a6d82 100644
--- a/third_party/crashpad/crashpad/util/numeric/int128_test.cc
+++ b/third_party/crashpad/crashpad/util/numeric/int128_test.cc
@@ -14,7 +14,10 @@
#include "util/numeric/int128.h"
-#include "base/macros.h"
+#include <stdint.h>
+
+#include "base/bit_cast.h"
+#include "build/build_config.h"
#include "gtest/gtest.h"
namespace crashpad {