diff --git a/bazel/mongo_src_rules.bzl b/bazel/mongo_src_rules.bzl index 8326f05ded4..df4725e2d39 100644 --- a/bazel/mongo_src_rules.bzl +++ b/bazel/mongo_src_rules.bzl @@ -203,10 +203,13 @@ DISABLE_3RD_PARTY_FEATURES = select({ "//bazel/config:compiler_type_clang": [ "-disable_warnings_for_third_party_libraries_clang", "thread_safety_warnings", + "first_party_gcc_or_clang_warnings", "-ubsan_third_party", ], "//bazel/config:compiler_type_gcc": [ "-disable_warnings_for_third_party_libraries_gcc", + "first_party_gcc_or_clang_warnings", + "first_party_gcc_warnings", "-ubsan_third_party", ], "//conditions:default": [], @@ -379,7 +382,8 @@ def mongo_cc_library( if name != "mongoca" and name != "cyrus_sasl_windows_test_plugin": deps += MONGO_GLOBAL_SRC_DEPS - features = features + DISABLE_3RD_PARTY_FEATURES + if not in_third_party: + features = features + DISABLE_3RD_PARTY_FEATURES else: srcs = _final_srcs_for_cc + private_hdrs @@ -585,7 +589,8 @@ def _mongo_cc_binary_and_test( srcs = _final_srcs_for_cc + private_hdrs deps += MONGO_GLOBAL_SRC_DEPS - features = features + DISABLE_3RD_PARTY_FEATURES + if not in_third_party: + features = features + DISABLE_3RD_PARTY_FEATURES else: # Non-mongo pkgs: append private headers as sources srcs = _final_srcs_for_cc + private_hdrs diff --git a/bazel/toolchains/cc/mongo_linux/mongo_linux_cc_toolchain_config.bzl b/bazel/toolchains/cc/mongo_linux/mongo_linux_cc_toolchain_config.bzl index 2a010aa3c34..355ced80644 100644 --- a/bazel/toolchains/cc/mongo_linux/mongo_linux_cc_toolchain_config.bzl +++ b/bazel/toolchains/cc/mongo_linux/mongo_linux_cc_toolchain_config.bzl @@ -939,6 +939,9 @@ def _impl(ctx): # compilers GCC >= 4.6. Error explained in # https://svn.boost.org/trac/boost/ticket/6136 . "-Wno-unused-but-set-variable", + + # Warn about trampolines that require executable stacks. + "-Wtrampolines", ])], ), ], @@ -1723,6 +1726,38 @@ def _impl(ctx): ], ) + first_party_gcc_or_clang_warnings_feature = feature( + name = "first_party_gcc_or_clang_warnings", + enabled = False, + flag_sets = [ + flag_set( + actions = all_compile_actions, + flag_groups = [flag_group(flags = [ + # Warn about issues with format strings. Using both -Wformat and -Wformat=2 + # is necessary to get all the format string warnings in both gcc and clang. + # Specifically, in clang -Wformat=2 does not imply -Wformat. + "-Wformat", + "-Wformat=2", + ])], + ), + ], + ) + + first_party_gcc_warnings_feature = feature( + name = "first_party_gcc_warnings", + enabled = False, + flag_sets = [ + flag_set( + actions = all_compile_actions, + flag_groups = [flag_group(flags = [ + # Warn about bidirectional control characters that could be used for + # underhanded code. + "-Wbidi-chars=any", + ])], + ), + ], + ) + disable_warnings_for_third_party_libraries_clang_feature = feature( name = "disable_warnings_for_third_party_libraries_clang", enabled = ctx.attr.compiler == COMPILERS.CLANG, @@ -1857,6 +1892,8 @@ def _impl(ctx): compress_debug_disable_feature, rpath_override_feature, warnings_as_errors_link_feature, + first_party_gcc_or_clang_warnings_feature, + first_party_gcc_warnings_feature, ] + get_common_features(ctx) + [ # These flags are at the bottom so they get applied after anything else. # These are things like the flags people apply directly on cc_library through copts/linkopts diff --git a/src/mongo/bson/util/builder.h b/src/mongo/bson/util/builder.h index d6504172d6f..c4570dd3317 100644 --- a/src/mongo/bson/util/builder.h +++ b/src/mongo/bson/util/builder.h @@ -64,6 +64,7 @@ #include #include #include +#include namespace mongo { @@ -749,7 +750,7 @@ public: StringBuilderImpl() {} StringBuilderImpl& operator<<(double x) { - return SBNUM(x, MONGO_DBL_SIZE, "%g"); + return appendUsingFmt(x, MONGO_DBL_SIZE); } StringBuilderImpl& operator<<(int x) { return appendIntegral(x, MONGO_S32_SIZE); @@ -773,11 +774,7 @@ public: return appendIntegral(x, MONGO_S16_SIZE); } StringBuilderImpl& operator<<(const void* x) { - if (sizeof(x) == 8) { - return SBNUM(x, MONGO_PTR_SIZE, "0x%llX"); - } else { - return SBNUM(x, MONGO_PTR_SIZE, "0x%lX"); - } + return appendUsingFmt(x, MONGO_PTR_SIZE); } StringBuilderImpl& operator<<(bool val) { *_buf.grow(1) = val ? '1' : '0'; @@ -876,13 +873,22 @@ private: return *this; } + size_t writeUsingFmt(char* dst, size_t maxSize, double val) { + return fmt::format_to_n(dst, maxSize, "{:g}", val).size; + } + + size_t writeUsingFmt(char* dst, size_t maxSize, const void* val) { + return fmt::format_to_n(dst, maxSize, "0x{:X}", uintptr_t(val)).size; + } + template - StringBuilderImpl& SBNUM(T val, int maxSize, const char* macro) { - int prev = _buf.len(); - int z = snprintf(_buf.grow(maxSize), maxSize, macro, (val)); - MONGO_verify(z >= 0); - MONGO_verify(z < maxSize); - _buf.setlen(prev + z); + StringBuilderImpl& appendUsingFmt(T val, size_t maxSize) { + static_assert(std::is_same_v || std::is_same_v); + size_t prev = _buf.len(); + size_t size = writeUsingFmt(_buf.grow(maxSize), maxSize, val); + MONGO_verify(size >= 0); + MONGO_verify(size < maxSize); + _buf.setlen(prev + size); return *this; } diff --git a/src/mongo/bson/util/builder_test.cpp b/src/mongo/bson/util/builder_test.cpp index 44e90fa6005..6c1b8fe9865 100644 --- a/src/mongo/bson/util/builder_test.cpp +++ b/src/mongo/bson/util/builder_test.cpp @@ -118,6 +118,22 @@ TEST(Builder, StackAllocatorShouldNotLeak) { // Let the builder go out of scope. If this leaks, it will trip the ASAN leak detector. } +TEST(Builder, StringBuilderFloatingPointExponentNotation) { + StringBuilder sb; + sb << 1000000.23456789; + ASSERT_EQUALS("1e+06", sb.str()); + + sb.reset(); + sb << 1234567.89; + ASSERT_EQUALS("1.23457e+06", sb.str()); +} + +TEST(Builder, StringBuilderFloatingPointPrecision) { + StringBuilder sb; + sb << 1.23456789; + ASSERT_EQUALS("1.23457", sb.str()); +} + template void testStringBuilderIntegral() { auto check = [](T num) { diff --git a/src/mongo/util/time_support.cpp b/src/mongo/util/time_support.cpp index ac3f1f76057..d180922ac70 100644 --- a/src/mongo/util/time_support.cpp +++ b/src/mongo/util/time_support.cpp @@ -165,19 +165,17 @@ std::string time_t_to_String_short(time_t t) { return buf; } -constexpr auto kUTCFilenameFormat = "%Y-%m-%dT%H-%M-%S"_sd; -constexpr auto kUTCFilenameFormatZ = "%Y-%m-%dT%H-%M-%SZ"_sd; - // Produces a UTC datetime string suitable for use in filenames. std::string terseCurrentTimeForFilename(bool appendZed) { struct tm t; time_t_to_Struct(time(nullptr), &t); - const auto fmt = appendZed ? kUTCFilenameFormatZ : kUTCFilenameFormat; const std::size_t expLen = appendZed ? 20 : 19; char buf[32]; - fassert(16226, strftime(buf, sizeof(buf), fmt.data(), &t) == expLen); + size_t bytesWritten = + strftime(buf, sizeof(buf), appendZed ? "%Y-%m-%dT%H-%M-%SZ" : "%Y-%m-%dT%H-%M-%S", &t); + fassert(16226, bytesWritten == expLen); return buf; }