diff --git a/absl/base/BUILD.bazel b/absl/base/BUILD.bazel index 1664a3512..816e592b5 100644 --- a/absl/base/BUILD.bazel +++ b/absl/base/BUILD.bazel @@ -118,7 +118,6 @@ cc_library( srcs = ["dynamic_annotations.cc"], hdrs = ["dynamic_annotations.h"], copts = ABSL_DEFAULT_COPTS, - defines = ["__CLANG_SUPPORT_DYN_ANNOTATION__"], linkopts = ABSL_DEFAULT_LINKOPTS, ) diff --git a/absl/base/CMakeLists.txt b/absl/base/CMakeLists.txt index 2df2e9713..292998b3b 100644 --- a/absl/base/CMakeLists.txt +++ b/absl/base/CMakeLists.txt @@ -108,8 +108,6 @@ absl_cc_library( "dynamic_annotations.cc" COPTS ${ABSL_DEFAULT_COPTS} - DEFINES - "__CLANG_SUPPORT_DYN_ANNOTATION__" PUBLIC ) diff --git a/absl/base/dynamic_annotations.h b/absl/base/dynamic_annotations.h index 65a54b447..2d9852607 100644 --- a/absl/base/dynamic_annotations.h +++ b/absl/base/dynamic_annotations.h @@ -140,10 +140,7 @@ #define ANNOTATE_MEMORY_IS_UNINITIALIZED(address, size) /* empty */ #endif /* DYNAMIC_ANNOTATIONS_ENABLED || MEMORY_SANITIZER */ -/* TODO(delesley) -- Replace __CLANG_SUPPORT_DYN_ANNOTATION__ with the - appropriate feature ID. */ -#if defined(__clang__) && (!defined(SWIG)) \ - && defined(__CLANG_SUPPORT_DYN_ANNOTATION__) +#if defined(__clang__) && !defined(SWIG) #if DYNAMIC_ANNOTATIONS_ENABLED == 0 #define ANNOTALYSIS_ENABLED diff --git a/absl/flags/BUILD.bazel b/absl/flags/BUILD.bazel index 685e39541..368108252 100644 --- a/absl/flags/BUILD.bazel +++ b/absl/flags/BUILD.bazel @@ -40,6 +40,7 @@ cc_library( deps = [ ":config", ":handle", + ":marshalling", ":registry", "//absl/base", "//absl/base:config", @@ -143,8 +144,6 @@ cc_library( "//absl/flags:__pkg__", ], deps = [ - ":config", - ":marshalling", "//absl/base:config", "//absl/base:core_headers", "//absl/base:fast_type_id", @@ -153,6 +152,22 @@ cc_library( ], ) +cc_library( + name = "private_handle_accessor", + srcs = [ + "internal/private_handle_accessor.cc", + ], + hdrs = [ + "internal/private_handle_accessor.h", + ], + copts = ABSL_DEFAULT_COPTS, + linkopts = ABSL_DEFAULT_LINKOPTS, + visibility = [ + "//absl/flags:__pkg__", + ], + deps = [":handle"], +) + cc_library( name = "registry", srcs = [ @@ -171,6 +186,7 @@ cc_library( deps = [ ":config", ":handle", + ":private_handle_accessor", "//absl/base:config", "//absl/base:core_headers", "//absl/base:raw_logging_internal", @@ -222,6 +238,7 @@ cc_library( ":flag_internal", ":handle", ":path_util", + ":private_handle_accessor", ":program_name", ":registry", "//absl/base:config", @@ -263,6 +280,7 @@ cc_library( ":flag", ":flag_internal", ":handle", + ":private_handle_accessor", ":program_name", ":registry", ":usage", @@ -289,6 +307,7 @@ cc_test( ":config", ":flag", ":handle", + ":private_handle_accessor", ":registry", "//absl/memory", "//absl/strings", diff --git a/absl/flags/CMakeLists.txt b/absl/flags/CMakeLists.txt index ec82ee1e3..e6b17c9b0 100644 --- a/absl/flags/CMakeLists.txt +++ b/absl/flags/CMakeLists.txt @@ -31,6 +31,7 @@ absl_cc_library( absl::config absl::flags_config absl::flags_handle + absl::flags_marshalling absl::flags_registry absl::synchronization absl::meta @@ -129,8 +130,6 @@ absl_cc_library( DEPS absl::config absl::fast_type_id - absl::flags_config - absl::flags_marshalling absl::core_headers absl::optional absl::raw_logging_internal @@ -138,6 +137,22 @@ absl_cc_library( absl::synchronization ) +# Internal-only target, do not depend on directly. +absl_cc_library( + NAME + flags_private_handle_accessor + SRCS + "internal/private_handle_accessor.cc" + HDRS + "internal/private_handle_accessor.h" + COPTS + ${ABSL_DEFAULT_COPTS} + LINKOPTS + ${ABSL_DEFAULT_LINKOPTS} + DEPS + absl::flags_handle +) + # Internal-only target, do not depend on directly. absl_cc_library( NAME @@ -156,6 +171,7 @@ absl_cc_library( absl::config absl::flags_config absl::flags_handle + absl::flags_private_handle_accessor absl::core_headers absl::raw_logging_internal absl::strings @@ -203,6 +219,7 @@ absl_cc_library( absl::flags_config absl::flags absl::flags_handle + absl::flags_private_handle_accessor absl::flags_internal absl::flags_path_util absl::flags_program_name @@ -248,6 +265,7 @@ absl_cc_library( absl::flags_config absl::flags absl::flags_handle + absl::flags_private_handle_accessor absl::flags_internal absl::flags_program_name absl::flags_registry @@ -270,6 +288,7 @@ absl_cc_test( absl::flags absl::flags_config absl::flags_handle + absl::flags_private_handle_accessor absl::flags_registry absl::memory absl::strings diff --git a/absl/flags/internal/commandlineflag.cc b/absl/flags/internal/commandlineflag.cc index c919fa1be..84112437d 100644 --- a/absl/flags/internal/commandlineflag.cc +++ b/absl/flags/internal/commandlineflag.cc @@ -28,33 +28,6 @@ bool CommandLineFlag::ParseFrom(absl::string_view value, std::string* error) { flags_internal::kProgrammaticChange, error); } -FlagFastTypeId PrivateHandleInterface::TypeId(const CommandLineFlag& flag) { - return flag.TypeId(); -} - -std::unique_ptr PrivateHandleInterface::SaveState( - CommandLineFlag* flag) { - return flag->SaveState(); -} - -bool PrivateHandleInterface::ValidateInputValue(const CommandLineFlag& flag, - absl::string_view value) { - return flag.ValidateInputValue(value); -} - -void PrivateHandleInterface::CheckDefaultValueParsingRoundtrip( - const CommandLineFlag& flag) { - flag.CheckDefaultValueParsingRoundtrip(); -} - -bool PrivateHandleInterface::ParseFrom(CommandLineFlag* flag, - absl::string_view value, - flags_internal::FlagSettingMode set_mode, - flags_internal::ValueSource source, - std::string* error) { - return flag->ParseFrom(value, set_mode, source, error); -} - } // namespace flags_internal ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/flags/internal/commandlineflag.h b/absl/flags/internal/commandlineflag.h index af5e05d59..2d3b794db 100644 --- a/absl/flags/internal/commandlineflag.h +++ b/absl/flags/internal/commandlineflag.h @@ -16,18 +16,12 @@ #ifndef ABSL_FLAGS_INTERNAL_COMMANDLINEFLAG_H_ #define ABSL_FLAGS_INTERNAL_COMMANDLINEFLAG_H_ -#include -#include - #include #include -#include #include "absl/base/config.h" #include "absl/base/internal/fast_type_id.h" #include "absl/base/macros.h" -#include "absl/flags/config.h" -#include "absl/flags/marshalling.h" #include "absl/strings/string_view.h" #include "absl/types/optional.h" @@ -147,7 +141,7 @@ class CommandLineFlag { ~CommandLineFlag() = default; private: - friend class PrivateHandleInterface; + friend class PrivateHandleAccessor; // Sets the value of the flag based on specified string `value`. If the flag // was successfully set to new value, it returns true. Otherwise, sets `error` @@ -181,29 +175,6 @@ class CommandLineFlag { virtual void CheckDefaultValueParsingRoundtrip() const = 0; }; -// This class serves as a trampoline to access private methods of -// CommandLineFlag. This class is intended for use exclusively internally inside -// of the Abseil Flags implementation -class PrivateHandleInterface { - public: - // Access to CommandLineFlag::TypeId. - static FlagFastTypeId TypeId(const CommandLineFlag& flag); - - // Access to CommandLineFlag::SaveState. - static std::unique_ptr SaveState(CommandLineFlag* flag); - - // Access to CommandLineFlag::ValidateInputValue. - static bool ValidateInputValue(const CommandLineFlag& flag, - absl::string_view value); - - // Access to CommandLineFlag::CheckDefaultValueParsingRoundtrip. - static void CheckDefaultValueParsingRoundtrip(const CommandLineFlag& flag); - - static bool ParseFrom(CommandLineFlag* flag, absl::string_view value, - flags_internal::FlagSettingMode set_mode, - flags_internal::ValueSource source, std::string* error); -}; - // This macro is the "source of truth" for the list of supported flag built-in // types. #define ABSL_FLAGS_INTERNAL_BUILTIN_TYPES(A) \ diff --git a/absl/flags/internal/commandlineflag_test.cc b/absl/flags/internal/commandlineflag_test.cc index 4aeb3bf4d..54d50fff3 100644 --- a/absl/flags/internal/commandlineflag_test.cc +++ b/absl/flags/internal/commandlineflag_test.cc @@ -20,6 +20,7 @@ #include "gtest/gtest.h" #include "absl/flags/flag.h" +#include "absl/flags/internal/private_handle_accessor.h" #include "absl/flags/internal/registry.h" #include "absl/flags/usage_config.h" #include "absl/memory/memory.h" @@ -122,52 +123,52 @@ TEST_F(CommandLineFlagTest, TestParseFromCurrentValue) { auto* flag_01 = flags::FindCommandLineFlag("int_flag"); EXPECT_FALSE(flag_01->IsSpecifiedOnCommandLine()); - EXPECT_TRUE(flags::PrivateHandleInterface::ParseFrom( + EXPECT_TRUE(flags::PrivateHandleAccessor::ParseFrom( flag_01, "11", flags::SET_FLAGS_VALUE, flags::kProgrammaticChange, &err)); EXPECT_EQ(absl::GetFlag(FLAGS_int_flag), 11); EXPECT_FALSE(flag_01->IsSpecifiedOnCommandLine()); - EXPECT_TRUE(flags::PrivateHandleInterface::ParseFrom( + EXPECT_TRUE(flags::PrivateHandleAccessor::ParseFrom( flag_01, "-123", flags::SET_FLAGS_VALUE, flags::kProgrammaticChange, &err)); EXPECT_EQ(absl::GetFlag(FLAGS_int_flag), -123); EXPECT_FALSE(flag_01->IsSpecifiedOnCommandLine()); - EXPECT_TRUE(!flags::PrivateHandleInterface::ParseFrom( + EXPECT_TRUE(!flags::PrivateHandleAccessor::ParseFrom( flag_01, "xyz", flags::SET_FLAGS_VALUE, flags::kProgrammaticChange, &err)); EXPECT_EQ(absl::GetFlag(FLAGS_int_flag), -123); EXPECT_EQ(err, "Illegal value 'xyz' specified for flag 'int_flag'"); EXPECT_FALSE(flag_01->IsSpecifiedOnCommandLine()); - EXPECT_TRUE(!flags::PrivateHandleInterface::ParseFrom( + EXPECT_TRUE(!flags::PrivateHandleAccessor::ParseFrom( flag_01, "A1", flags::SET_FLAGS_VALUE, flags::kProgrammaticChange, &err)); EXPECT_EQ(absl::GetFlag(FLAGS_int_flag), -123); EXPECT_EQ(err, "Illegal value 'A1' specified for flag 'int_flag'"); EXPECT_FALSE(flag_01->IsSpecifiedOnCommandLine()); - EXPECT_TRUE(flags::PrivateHandleInterface::ParseFrom( + EXPECT_TRUE(flags::PrivateHandleAccessor::ParseFrom( flag_01, "0x10", flags::SET_FLAGS_VALUE, flags::kProgrammaticChange, &err)); EXPECT_EQ(absl::GetFlag(FLAGS_int_flag), 16); EXPECT_FALSE(flag_01->IsSpecifiedOnCommandLine()); - EXPECT_TRUE(flags::PrivateHandleInterface::ParseFrom( + EXPECT_TRUE(flags::PrivateHandleAccessor::ParseFrom( flag_01, "011", flags::SET_FLAGS_VALUE, flags::kCommandLine, &err)); EXPECT_EQ(absl::GetFlag(FLAGS_int_flag), 11); EXPECT_TRUE(flag_01->IsSpecifiedOnCommandLine()); - EXPECT_TRUE(!flags::PrivateHandleInterface::ParseFrom( + EXPECT_TRUE(!flags::PrivateHandleAccessor::ParseFrom( flag_01, "", flags::SET_FLAGS_VALUE, flags::kProgrammaticChange, &err)); EXPECT_EQ(err, "Illegal value '' specified for flag 'int_flag'"); auto* flag_02 = flags::FindCommandLineFlag("string_flag"); - EXPECT_TRUE(flags::PrivateHandleInterface::ParseFrom( + EXPECT_TRUE(flags::PrivateHandleAccessor::ParseFrom( flag_02, "xyz", flags::SET_FLAGS_VALUE, flags::kProgrammaticChange, &err)); EXPECT_EQ(absl::GetFlag(FLAGS_string_flag), "xyz"); - EXPECT_TRUE(flags::PrivateHandleInterface::ParseFrom( + EXPECT_TRUE(flags::PrivateHandleAccessor::ParseFrom( flag_02, "", flags::SET_FLAGS_VALUE, flags::kProgrammaticChange, &err)); EXPECT_EQ(absl::GetFlag(FLAGS_string_flag), ""); } @@ -179,14 +180,14 @@ TEST_F(CommandLineFlagTest, TestParseFromDefaultValue) { auto* flag_01 = flags::FindCommandLineFlag("int_flag"); - EXPECT_TRUE(flags::PrivateHandleInterface::ParseFrom( + EXPECT_TRUE(flags::PrivateHandleAccessor::ParseFrom( flag_01, "111", flags::SET_FLAGS_DEFAULT, flags::kProgrammaticChange, &err)); EXPECT_EQ(flag_01->DefaultValue(), "111"); auto* flag_02 = flags::FindCommandLineFlag("string_flag"); - EXPECT_TRUE(flags::PrivateHandleInterface::ParseFrom( + EXPECT_TRUE(flags::PrivateHandleAccessor::ParseFrom( flag_02, "abc", flags::SET_FLAGS_DEFAULT, flags::kProgrammaticChange, &err)); EXPECT_EQ(flag_02->DefaultValue(), "abc"); @@ -199,24 +200,24 @@ TEST_F(CommandLineFlagTest, TestParseFromIfDefault) { auto* flag_01 = flags::FindCommandLineFlag("int_flag"); - EXPECT_TRUE(flags::PrivateHandleInterface::ParseFrom( + EXPECT_TRUE(flags::PrivateHandleAccessor::ParseFrom( flag_01, "22", flags::SET_FLAG_IF_DEFAULT, flags::kProgrammaticChange, &err)) << err; EXPECT_EQ(absl::GetFlag(FLAGS_int_flag), 22); - EXPECT_TRUE(flags::PrivateHandleInterface::ParseFrom( + EXPECT_TRUE(flags::PrivateHandleAccessor::ParseFrom( flag_01, "33", flags::SET_FLAG_IF_DEFAULT, flags::kProgrammaticChange, &err)); EXPECT_EQ(absl::GetFlag(FLAGS_int_flag), 22); // EXPECT_EQ(err, "ERROR: int_flag is already set to 22"); // Reset back to default value - EXPECT_TRUE(flags::PrivateHandleInterface::ParseFrom( + EXPECT_TRUE(flags::PrivateHandleAccessor::ParseFrom( flag_01, "201", flags::SET_FLAGS_VALUE, flags::kProgrammaticChange, &err)); - EXPECT_TRUE(flags::PrivateHandleInterface::ParseFrom( + EXPECT_TRUE(flags::PrivateHandleAccessor::ParseFrom( flag_01, "33", flags::SET_FLAG_IF_DEFAULT, flags::kProgrammaticChange, &err)); EXPECT_EQ(absl::GetFlag(FLAGS_int_flag), 201); diff --git a/absl/flags/internal/flag.h b/absl/flags/internal/flag.h index b22088245..f53f484f8 100644 --- a/absl/flags/internal/flag.h +++ b/absl/flags/internal/flag.h @@ -31,6 +31,7 @@ #include "absl/flags/config.h" #include "absl/flags/internal/commandlineflag.h" #include "absl/flags/internal/registry.h" +#include "absl/flags/marshalling.h" #include "absl/memory/memory.h" #include "absl/meta/type_traits.h" #include "absl/strings/str_cat.h" diff --git a/absl/flags/internal/private_handle_accessor.cc b/absl/flags/internal/private_handle_accessor.cc new file mode 100644 index 000000000..ec5776bb0 --- /dev/null +++ b/absl/flags/internal/private_handle_accessor.cc @@ -0,0 +1,52 @@ +// +// Copyright 2020 The Abseil Authors. +// +// 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 +// +// https://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. + +#include "absl/flags/internal/private_handle_accessor.h" + +namespace absl { +ABSL_NAMESPACE_BEGIN +namespace flags_internal { + +FlagFastTypeId PrivateHandleAccessor::TypeId(const CommandLineFlag& flag) { + return flag.TypeId(); +} + +std::unique_ptr PrivateHandleAccessor::SaveState( + CommandLineFlag* flag) { + return flag->SaveState(); +} + +bool PrivateHandleAccessor::ValidateInputValue(const CommandLineFlag& flag, + absl::string_view value) { + return flag.ValidateInputValue(value); +} + +void PrivateHandleAccessor::CheckDefaultValueParsingRoundtrip( + const CommandLineFlag& flag) { + flag.CheckDefaultValueParsingRoundtrip(); +} + +bool PrivateHandleAccessor::ParseFrom(CommandLineFlag* flag, + absl::string_view value, + flags_internal::FlagSettingMode set_mode, + flags_internal::ValueSource source, + std::string* error) { + return flag->ParseFrom(value, set_mode, source, error); +} + +} // namespace flags_internal +ABSL_NAMESPACE_END +} // namespace absl + diff --git a/absl/flags/internal/private_handle_accessor.h b/absl/flags/internal/private_handle_accessor.h new file mode 100644 index 000000000..fbb4409cd --- /dev/null +++ b/absl/flags/internal/private_handle_accessor.h @@ -0,0 +1,52 @@ +// +// Copyright 2020 The Abseil Authors. +// +// 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 +// +// https://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. + +#ifndef ABSL_FLAGS_INTERNAL_PRIVATE_HANDLE_ACCESSOR_H_ +#define ABSL_FLAGS_INTERNAL_PRIVATE_HANDLE_ACCESSOR_H_ + +#include "absl/flags/internal/commandlineflag.h" + +namespace absl { +ABSL_NAMESPACE_BEGIN +namespace flags_internal { + +// This class serves as a trampoline to access private methods of +// CommandLineFlag. This class is intended for use exclusively internally inside +// of the Abseil Flags implementation. +class PrivateHandleAccessor { + public: + // Access to CommandLineFlag::TypeId. + static FlagFastTypeId TypeId(const CommandLineFlag& flag); + + // Access to CommandLineFlag::SaveState. + static std::unique_ptr SaveState(CommandLineFlag* flag); + + // Access to CommandLineFlag::ValidateInputValue. + static bool ValidateInputValue(const CommandLineFlag& flag, + absl::string_view value); + + // Access to CommandLineFlag::CheckDefaultValueParsingRoundtrip. + static void CheckDefaultValueParsingRoundtrip(const CommandLineFlag& flag); + + static bool ParseFrom(CommandLineFlag* flag, absl::string_view value, + flags_internal::FlagSettingMode set_mode, + flags_internal::ValueSource source, std::string* error); +}; + +} // namespace flags_internal +ABSL_NAMESPACE_END +} // namespace absl + +#endif // ABSL_FLAGS_INTERNAL_PRIVATE_HANDLE_ACCESSOR_H_ diff --git a/absl/flags/internal/registry.cc b/absl/flags/internal/registry.cc index 62b5b40d8..3b941f04c 100644 --- a/absl/flags/internal/registry.cc +++ b/absl/flags/internal/registry.cc @@ -29,6 +29,7 @@ #include "absl/base/internal/raw_logging.h" #include "absl/base/thread_annotations.h" #include "absl/flags/internal/commandlineflag.h" +#include "absl/flags/internal/private_handle_accessor.h" #include "absl/flags/usage_config.h" #include "absl/strings/str_cat.h" #include "absl/strings/string_view.h" @@ -127,8 +128,8 @@ void FlagRegistry::RegisterFlag(CommandLineFlag* flag) { (flag->IsRetired() ? old_flag->Filename() : flag->Filename()), "'."), true); - } else if (flags_internal::PrivateHandleInterface::TypeId(*flag) != - flags_internal::PrivateHandleInterface::TypeId(*old_flag)) { + } else if (flags_internal::PrivateHandleAccessor::TypeId(*flag) != + flags_internal::PrivateHandleAccessor::TypeId(*old_flag)) { flags_internal::ReportUsageError( absl::StrCat("Flag '", flag->Name(), "' was defined more than once but with " @@ -206,7 +207,7 @@ class FlagSaverImpl { assert(backup_registry_.empty()); // call only once! flags_internal::ForEachFlag([&](flags_internal::CommandLineFlag* flag) { if (auto flag_state = - flags_internal::PrivateHandleInterface::SaveState(flag)) { + flags_internal::PrivateHandleAccessor::SaveState(flag)) { backup_registry_.emplace_back(std::move(flag_state)); } }); diff --git a/absl/flags/internal/type_erased.cc b/absl/flags/internal/type_erased.cc index adeb7a154..3cfc9b2df 100644 --- a/absl/flags/internal/type_erased.cc +++ b/absl/flags/internal/type_erased.cc @@ -22,6 +22,7 @@ #include "absl/base/config.h" #include "absl/base/internal/raw_logging.h" #include "absl/flags/internal/commandlineflag.h" +#include "absl/flags/internal/private_handle_accessor.h" #include "absl/flags/internal/registry.h" #include "absl/flags/usage_config.h" #include "absl/strings/string_view.h" @@ -56,7 +57,7 @@ bool SetCommandLineOptionWithMode(absl::string_view name, if (!flag || flag->IsRetired()) return false; std::string error; - if (!flags_internal::PrivateHandleInterface::ParseFrom( + if (!flags_internal::PrivateHandleAccessor::ParseFrom( flag, value, set_mode, kProgrammaticChange, &error)) { // Errors here are all of the form: the provided name was a recognized // flag, but the value was invalid (bad type, or validation failed). @@ -74,8 +75,8 @@ bool IsValidFlagValue(absl::string_view name, absl::string_view value) { return flag != nullptr && (flag->IsRetired() || - flags_internal::PrivateHandleInterface::ValidateInputValue(*flag, - value)); + flags_internal::PrivateHandleAccessor::ValidateInputValue(*flag, + value)); } // -------------------------------------------------------------------- diff --git a/absl/flags/internal/usage.cc b/absl/flags/internal/usage.cc index 9d856c87a..10accc46f 100644 --- a/absl/flags/internal/usage.cc +++ b/absl/flags/internal/usage.cc @@ -27,6 +27,7 @@ #include "absl/flags/internal/commandlineflag.h" #include "absl/flags/internal/flag.h" #include "absl/flags/internal/path_util.h" +#include "absl/flags/internal/private_handle_accessor.h" #include "absl/flags/internal/program_name.h" #include "absl/flags/internal/registry.h" #include "absl/flags/usage_config.h" diff --git a/absl/flags/parse.cc b/absl/flags/parse.cc index cc1349098..66a28a93c 100644 --- a/absl/flags/parse.cc +++ b/absl/flags/parse.cc @@ -39,6 +39,7 @@ #include "absl/flags/internal/commandlineflag.h" #include "absl/flags/internal/flag.h" #include "absl/flags/internal/parse.h" +#include "absl/flags/internal/private_handle_accessor.h" #include "absl/flags/internal/program_name.h" #include "absl/flags/internal/registry.h" #include "absl/flags/internal/usage.h" @@ -298,7 +299,7 @@ void CheckDefaultValuesParsingRoundtrip() { ABSL_FLAGS_INTERNAL_BUILTIN_TYPES(IGNORE_TYPE) #undef IGNORE_TYPE - flags_internal::PrivateHandleInterface::CheckDefaultValueParsingRoundtrip( + flags_internal::PrivateHandleAccessor::CheckDefaultValueParsingRoundtrip( *flag); }); #endif @@ -697,7 +698,7 @@ std::vector ParseCommandLineImpl(int argc, char* argv[], if (flag->IsRetired()) continue; std::string error; - if (!flags_internal::PrivateHandleInterface::ParseFrom( + if (!flags_internal::PrivateHandleAccessor::ParseFrom( flag, value, SET_FLAGS_VALUE, kCommandLine, &error)) { flags_internal::ReportUsageError(error, true); success = false; diff --git a/absl/strings/internal/str_format/convert_test.cc b/absl/strings/internal/str_format/convert_test.cc index dd167f76e..20c6229fc 100644 --- a/absl/strings/internal/str_format/convert_test.cc +++ b/absl/strings/internal/str_format/convert_test.cc @@ -704,6 +704,31 @@ TEST_F(FormatConvertTest, FloatRound) { "1837869002408041296803276054561138153076171875"); } +// We don't actually store the results. This is just to exercise the rest of the +// machinery. +struct NullSink { + friend void AbslFormatFlush(NullSink *sink, string_view str) {} +}; + +template +bool FormatWithNullSink(absl::string_view fmt, const T &... a) { + NullSink sink; + FormatArgImpl args[] = {FormatArgImpl(a)...}; + return FormatUntyped(&sink, UntypedFormatSpecImpl(fmt), absl::MakeSpan(args)); +} + +TEST_F(FormatConvertTest, ExtremeWidthPrecision) { + for (const char *fmt : {"f"}) { + for (double d : {1e-100, 1.0, 1e100}) { + constexpr int max = std::numeric_limits::max(); + EXPECT_TRUE(FormatWithNullSink(std::string("%.*") + fmt, max, d)); + EXPECT_TRUE(FormatWithNullSink(std::string("%1.*") + fmt, max, d)); + EXPECT_TRUE(FormatWithNullSink(std::string("%*") + fmt, max, d)); + EXPECT_TRUE(FormatWithNullSink(std::string("%*.*") + fmt, max, max, d)); + } + } +} + TEST_F(FormatConvertTest, LongDouble) { #ifdef _MSC_VER // MSVC has a different rounding policy than us so we can't test our diff --git a/absl/strings/internal/str_format/float_conversion.cc b/absl/strings/internal/str_format/float_conversion.cc index cdccc86f5..a761a5a5f 100644 --- a/absl/strings/internal/str_format/float_conversion.cc +++ b/absl/strings/internal/str_format/float_conversion.cc @@ -440,8 +440,10 @@ struct Padding { int right_spaces; }; -Padding ExtraWidthToPadding(int total_size, const FormatState &state) { - int missing_chars = std::max(state.conv.width() - total_size, 0); +Padding ExtraWidthToPadding(size_t total_size, const FormatState &state) { + if (state.conv.width() < 0 || state.conv.width() <= total_size) + return {0, 0, 0}; + int missing_chars = state.conv.width() - total_size; if (state.conv.has_left_flag()) { return {0, 0, missing_chars}; } else if (state.conv.has_zero_flag()) { @@ -462,8 +464,8 @@ void FinalPrint(absl::string_view data, int trailing_zeros, } auto padding = - ExtraWidthToPadding((state.sign_char != '\0' ? 1 : 0) + - static_cast(data.size()) + trailing_zeros, + ExtraWidthToPadding((state.sign_char != '\0' ? 1 : 0) + data.size() + + static_cast(trailing_zeros), state); state.sink->Append(padding.left_spaces, ' '); @@ -536,8 +538,9 @@ void FormatFFast(Int v, int exp, const FormatState &state) { // worry about anything after the `.`. void FormatFPositiveExpSlow(uint128 v, int exp, const FormatState &state) { BinaryToDecimal::RunConversion(v, exp, [&](BinaryToDecimal btd) { - const int total_digits = - btd.TotalDigits() + (state.ShouldPrintDot() ? state.precision + 1 : 0); + const size_t total_digits = + btd.TotalDigits() + + (state.ShouldPrintDot() ? static_cast(state.precision) + 1 : 0); const auto padding = ExtraWidthToPadding( total_digits + (state.sign_char != '\0' ? 1 : 0), state); @@ -562,8 +565,9 @@ void FormatFPositiveExpSlow(uint128 v, int exp, const FormatState &state) { // This one is guaranteed to be < 1.0, so we don't have to worry about integral // digits. void FormatFNegativeExpSlow(uint128 v, int exp, const FormatState &state) { - const int total_digits = - /* 0 */ 1 + (state.ShouldPrintDot() ? state.precision + 1 : 0); + const size_t total_digits = + /* 0 */ 1 + + (state.ShouldPrintDot() ? static_cast(state.precision) + 1 : 0); auto padding = ExtraWidthToPadding(total_digits + (state.sign_char ? 1 : 0), state); padding.zeros += 1;