Export of internal Abseil changes

--
620668e56950d7cfc39db2cd321adf265199ad77 by Abseil Team <absl-team@google.com>:

absl::random compiles (at least for some cases) with -Wconversion -Wsign-compare

PiperOrigin-RevId: 419595521

--
746651e5fbcab6080d25c4eef8617fc289a448f6 by Abseil Team <absl-team@google.com>:

Annotate FlagImpl storage buffer

Flag type can contain legit uninitialized bits, e.g. padding.
When the code calls bit_cast as int64_t, it will contain those bits as well.
Then when we pass the int into the store it's UB for C++ and will be
reported by the new msan.

PiperOrigin-RevId: 418666492
GitOrigin-RevId: 620668e56950d7cfc39db2cd321adf265199ad77
Change-Id: Idd1190f5c98a0a13c4019f3d92cec0313822084c
pull/1095/head
Abseil Team 3 years ago committed by Andy Getz
parent 04610889a9
commit c498947f8c
  1. 1
      absl/flags/BUILD.bazel
  2. 1
      absl/flags/CMakeLists.txt
  3. 3
      absl/flags/internal/flag.cc
  4. 8
      absl/random/bernoulli_distribution.h

@ -204,6 +204,7 @@ cc_library(
"//absl/base",
"//absl/base:config",
"//absl/base:core_headers",
"//absl/base:dynamic_annotations",
"//absl/memory",
"//absl/meta:type_traits",
"//absl/strings",

@ -105,6 +105,7 @@ absl_cc_library(
${ABSL_DEFAULT_LINKOPTS}
DEPS
absl::config
absl::dynamic_annotations
absl::fast_type_id
)

@ -30,6 +30,7 @@
#include "absl/base/call_once.h"
#include "absl/base/casts.h"
#include "absl/base/config.h"
#include "absl/base/dynamic_annotations.h"
#include "absl/base/optimization.h"
#include "absl/flags/config.h"
#include "absl/flags/internal/commandlineflag.h"
@ -160,6 +161,8 @@ void FlagImpl::Init() {
std::memcpy(buf.data() + Sizeof(op_), &initialized,
sizeof(initialized));
}
// Type can contain valid uninitialized bits, e.g. padding.
ABSL_ANNOTATE_MEMORY_IS_INITIALIZED(buf.data(), buf.size());
OneWordValue().store(absl::bit_cast<int64_t>(buf),
std::memory_order_release);
break;

@ -138,16 +138,16 @@ bool bernoulli_distribution::Generate(double p,
// 64 bits.
//
// Second, `c` is constructed by first casting explicitly to a signed
// integer and then converting implicitly to an unsigned integer of the same
// integer and then casting explicitly to an unsigned integer of the same
// size. This is done because the hardware conversion instructions produce
// signed integers from double; if taken as a uint64_t the conversion would
// be wrong for doubles greater than 2^63 (not relevant in this use-case).
// If converted directly to an unsigned integer, the compiler would end up
// emitting code to handle such large values that are not relevant due to
// the known bounds on `c`. To avoid these extra instructions this
// implementation converts first to the signed type and then use the
// implicit conversion to unsigned (which is a no-op).
const uint64_t c = static_cast<int64_t>(p * kP32);
// implementation converts first to the signed type and then convert to
// unsigned (which is a no-op).
const uint64_t c = static_cast<uint64_t>(static_cast<int64_t>(p * kP32));
const uint32_t v = fast_u32(g);
// FAST PATH: this path fails with probability 1/2^32. Note that simply
// returning v <= c would approximate P very well (up to an absolute error

Loading…
Cancel
Save