Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
3bdb551
Silence output on check for GNU parallel binary
eramongodb Nov 12, 2025
6c28bb8
CXX-2338 migrate clang-tidy to rhel9-latest distro
eramongodb Nov 12, 2025
2f728ec
Filter clang-tidy task to library sources only
eramongodb Nov 12, 2025
e0f3d40
clang-tidy: dump config for 21.1.1
eramongodb Nov 12, 2025
35e3864
clang-tidy: set User to empty string
eramongodb Nov 12, 2025
1dbcb5b
clang-tidy: exclude non-includable headers
eramongodb Nov 12, 2025
fc3b988
clang-tidy: convert checks string into list
eramongodb Nov 12, 2025
4e8c3bc
clang-tidy: remove redundant checks in list
eramongodb Nov 12, 2025
012d082
Merge remote-tracking branch 'upstream/master' into cxx-2139
eramongodb Nov 14, 2025
59f4f51
Merge remote-tracking branch 'upstream/master' into cxx-2139
eramongodb Nov 19, 2025
2690211
Merge remote-tracking branch 'upstream/master' into HEAD
eramongodb Dec 3, 2025
be72dec
Upgrade all not-currently-warning default warnings to errors
eramongodb Dec 3, 2025
e19782b
Address cert-oop54-cpp warnings
eramongodb Dec 3, 2025
9df3fff
Address cppcoreguidelines-init-variables warnings
eramongodb Dec 3, 2025
e72fc6f
Address cppcoreguidelines-pro-type-static-cast-downcast warning
eramongodb Dec 3, 2025
14b6d78
Address cppcoreguidelines-prefer-member-initializer warnings
eramongodb Dec 3, 2025
429a3de
Address cppcoreguidelines-use-default-member-init warnings
eramongodb Dec 3, 2025
fc90141
Address cppcoreguidelines-non-private-member-variables-in-classes war…
eramongodb Dec 3, 2025
d1cb014
Address misc-throw-by-value-catch-by-reference warnings
eramongodb Dec 3, 2025
83cd0b8
Encapsulate v1::pipeline::impl::_idx invariants in a separate class
eramongodb Dec 3, 2025
615296e
Resolve merge conflict with upstream/master in advance
eramongodb Dec 4, 2025
9fd8488
Merge remote-tracking branch 'upstream/master' into HEAD
eramongodb Dec 4, 2025
e6d518f
Disable cppcoreguidelines-pro-type-union-access
eramongodb Dec 4, 2025
624d0be
Disable cppcoreguidelines-pro-bounds-array-to-pointer-decay
eramongodb Dec 4, 2025
6f579cc
Disable cppcoreguidelines-pro-bounds-pointer-arithmetic
eramongodb Dec 4, 2025
e534c74
Suppress cppcoreguidelines-pro-bounds-constant-array-index
eramongodb Dec 4, 2025
b136bc5
Suppress cppcoreguidelines-owning-memory warnings
eramongodb Dec 4, 2025
ea16657
Suppress cppcoreguidelines-pro-type-reinterpret-cast
eramongodb Dec 4, 2025
5dd83af
Address cppcoreguidelines-avoid-magic-numbers warnings
eramongodb Dec 4, 2025
6d037be
Address cppcoreguidelines-pro-type-const-cast warnings
eramongodb Dec 4, 2025
8737378
Address cppcoreguidelines-pro-type-member-init warnings
eramongodb Dec 4, 2025
03b583b
Address cppcoreguidelines-avoid-c-arrays warnings
eramongodb Dec 4, 2025
e162a99
Address cppcoreguidelines-use-enum-class warnings
eramongodb Dec 4, 2025
a13a33e
Suppress cppcoreguidelines-rvalue-reference-param-not-moved
eramongodb Dec 4, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
130 changes: 128 additions & 2 deletions .clang-tidy
Original file line number Diff line number Diff line change
@@ -1,2 +1,128 @@
Checks: 'clang-diagnostic-*,clang-analyzer-*,-*,cert-*,cppcoreguidelines-*,clang-analyzer-*'
WarningsAsErrors: ''
---
Checks:
- -*
- cert-*
- cppcoreguidelines-*
- clang-analyzer-*'
- -cppcoreguidelines-pro-bounds-array-to-pointer-decay # Noise.
- -cppcoreguidelines-pro-bounds-constant-array-index # Noise.
- -cppcoreguidelines-pro-bounds-pointer-arithmetic # Noise.
- -cppcoreguidelines-pro-type-union-access # Requires C++17 or newer for `std::variant`.
WarningsAsErrors: '*,-cert-err58-cpp,-cppcoreguidelines-avoid-do-while,-cppcoreguidelines-avoid-non-const-global-variables,-cppcoreguidelines-pro-type-union-access,-cppcoreguidelines-pro-type-vararg,-cppcoreguidelines-rvalue-reference-param-not-moved'
HeaderFileExtensions:
- ''
- h
- hh
- hpp
- hxx
ImplementationFileExtensions:
- c
- cc
- cpp
- cxx
HeaderFilterRegex: ''
ExcludeHeaderFilterRegex: '(?:.*/bsoncxx/enums/.*|.*/(?:prelude|postlude)\.hpp$)'
FormatStyle: none
User: ''
CheckOptions:
cert-arr39-c.WarnOnOffsetDividedBySizeOf: 'true'
cert-arr39-c.WarnOnSizeOfCompareToConstant: 'false'
cert-arr39-c.WarnOnSizeOfConstant: 'false'
cert-arr39-c.WarnOnSizeOfInLoopTermination: 'true'
cert-arr39-c.WarnOnSizeOfIntegerExpression: 'false'
cert-arr39-c.WarnOnSizeOfPointer: 'false'
cert-arr39-c.WarnOnSizeOfPointerToAggregate: 'false'
cert-arr39-c.WarnOnSizeOfThis: 'false'
cert-ctr56-cpp.IgnoreInheritedVirtualFunctions: 'false'
cert-dcl16-c.IgnoreMacros: 'true'
cert-dcl16-c.NewSuffixes: 'L;LL;LU;LLU'
cert-dcl37-c.AggressiveDependentMemberLookup: 'false'
cert-dcl37-c.AllowedIdentifiers: ''
cert-dcl37-c.Invert: 'false'
cert-dcl51-cpp.AggressiveDependentMemberLookup: 'false'
cert-dcl51-cpp.AllowedIdentifiers: ''
cert-dcl51-cpp.Invert: 'false'
cert-err09-cpp.CheckThrowTemporaries: 'true'
cert-err09-cpp.MaxSize: '18446744073709551615'
cert-err09-cpp.WarnOnLargeObjects: 'false'
cert-err33-c.AllowCastToVoid: 'true'
cert-err33-c.CheckedFunctions: '^::aligned_alloc$;^::asctime_s$;^::at_quick_exit$;^::atexit$;^::bsearch$;^::bsearch_s$;^::btowc$;^::c16rtomb$;^::c32rtomb$;^::calloc$;^::clock$;^::cnd_broadcast$;^::cnd_init$;^::cnd_signal$;^::cnd_timedwait$;^::cnd_wait$;^::ctime_s$;^::fclose$;^::fflush$;^::fgetc$;^::fgetpos$;^::fgets$;^::fgetwc$;^::fopen$;^::fopen_s$;^::fprintf$;^::fprintf_s$;^::fputc$;^::fputs$;^::fputwc$;^::fputws$;^::fread$;^::freopen$;^::freopen_s$;^::fscanf$;^::fscanf_s$;^::fseek$;^::fsetpos$;^::ftell$;^::fwprintf$;^::fwprintf_s$;^::fwrite$;^::fwscanf$;^::fwscanf_s$;^::getc$;^::getchar$;^::getenv$;^::getenv_s$;^::gets_s$;^::getwc$;^::getwchar$;^::gmtime$;^::gmtime_s$;^::localtime$;^::localtime_s$;^::malloc$;^::mbrtoc16$;^::mbrtoc32$;^::mbsrtowcs$;^::mbsrtowcs_s$;^::mbstowcs$;^::mbstowcs_s$;^::memchr$;^::mktime$;^::mtx_init$;^::mtx_lock$;^::mtx_timedlock$;^::mtx_trylock$;^::mtx_unlock$;^::printf_s$;^::putc$;^::putwc$;^::raise$;^::realloc$;^::remove$;^::rename$;^::scanf$;^::scanf_s$;^::setlocale$;^::setvbuf$;^::signal$;^::snprintf$;^::snprintf_s$;^::sprintf$;^::sprintf_s$;^::sscanf$;^::sscanf_s$;^::strchr$;^::strerror_s$;^::strftime$;^::strpbrk$;^::strrchr$;^::strstr$;^::strtod$;^::strtof$;^::strtoimax$;^::strtok$;^::strtok_s$;^::strtol$;^::strtold$;^::strtoll$;^::strtoul$;^::strtoull$;^::strtoumax$;^::strxfrm$;^::swprintf$;^::swprintf_s$;^::swscanf$;^::swscanf_s$;^::thrd_create$;^::thrd_detach$;^::thrd_join$;^::thrd_sleep$;^::time$;^::timespec_get$;^::tmpfile$;^::tmpfile_s$;^::tmpnam$;^::tmpnam_s$;^::tss_create$;^::tss_get$;^::tss_set$;^::ungetc$;^::ungetwc$;^::vfprintf$;^::vfprintf_s$;^::vfscanf$;^::vfscanf_s$;^::vfwprintf$;^::vfwprintf_s$;^::vfwscanf$;^::vfwscanf_s$;^::vprintf_s$;^::vscanf$;^::vscanf_s$;^::vsnprintf$;^::vsnprintf_s$;^::vsprintf$;^::vsprintf_s$;^::vsscanf$;^::vsscanf_s$;^::vswprintf$;^::vswprintf_s$;^::vswscanf$;^::vswscanf_s$;^::vwprintf_s$;^::vwscanf$;^::vwscanf_s$;^::wcrtomb$;^::wcschr$;^::wcsftime$;^::wcspbrk$;^::wcsrchr$;^::wcsrtombs$;^::wcsrtombs_s$;^::wcsstr$;^::wcstod$;^::wcstof$;^::wcstoimax$;^::wcstok$;^::wcstok_s$;^::wcstol$;^::wcstold$;^::wcstoll$;^::wcstombs$;^::wcstombs_s$;^::wcstoul$;^::wcstoull$;^::wcstoumax$;^::wcsxfrm$;^::wctob$;^::wctrans$;^::wctype$;^::wmemchr$;^::wprintf_s$;^::wscanf$;^::wscanf_s$'
cert-err33-c.CheckedReturnTypes: '^::std::error_code$;^::std::error_condition$;^::std::errc$;^::std::expected$;^::boost::system::error_code$'
cert-err61-cpp.CheckThrowTemporaries: 'true'
cert-err61-cpp.MaxSize: '18446744073709551615'
cert-err61-cpp.WarnOnLargeObjects: 'false'
cert-int09-c.AllowExplicitSequentialInitialValues: 'true'
cert-int09-c.AllowExplicitZeroFirstInitialValue: 'true'
cert-msc24-c.CustomFunctions: ''
cert-msc24-c.ReportDefaultFunctions: 'true'
cert-msc24-c.ReportMoreUnsafeFunctions: 'true'
cert-msc32-c.DisallowedSeedTypes: 'time_t,std::time_t'
cert-msc33-c.CustomFunctions: ''
cert-msc33-c.ReportDefaultFunctions: 'true'
cert-msc33-c.ReportMoreUnsafeFunctions: 'true'
cert-msc51-cpp.DisallowedSeedTypes: 'time_t,std::time_t'
cert-msc54-cpp.AsyncSafeFunctionSet: POSIX
cert-oop54-cpp.WarnOnlyIfThisHasSuspiciousField: 'false'
cert-oop57-cpp.MemCmpNames: ''
cert-oop57-cpp.MemCpyNames: ''
cert-oop57-cpp.MemSetNames: ''
cert-sig30-c.AsyncSafeFunctionSet: POSIX
cert-str34-c.CharTypdefsToIgnore: ''
cert-str34-c.DiagnoseSignedUnsignedCharComparisons: 'false'
cppcoreguidelines-avoid-c-arrays.AllowStringArrays: 'false'
cppcoreguidelines-avoid-do-while.IgnoreMacros: 'false'
cppcoreguidelines-avoid-goto.IgnoreMacros: 'false'
cppcoreguidelines-avoid-magic-numbers.IgnoreAllFloatingPointValues: 'false'
cppcoreguidelines-avoid-magic-numbers.IgnoreBitFieldsWidths: 'true'
cppcoreguidelines-avoid-magic-numbers.IgnorePowersOf2IntegerValues: 'false'
cppcoreguidelines-avoid-magic-numbers.IgnoreTypeAliases: 'false'
cppcoreguidelines-avoid-magic-numbers.IgnoreUserDefinedLiterals: 'false'
cppcoreguidelines-avoid-magic-numbers.IgnoredFloatingPointValues: '1.0;100.0;'
cppcoreguidelines-avoid-magic-numbers.IgnoredIntegerValues: '1;2;3;4;'
cppcoreguidelines-avoid-non-const-global-variables.AllowInternalLinkage: 'false'
cppcoreguidelines-explicit-virtual-functions.AllowOverrideAndFinal: 'false'
cppcoreguidelines-explicit-virtual-functions.FinalSpelling: final
cppcoreguidelines-explicit-virtual-functions.IgnoreDestructors: 'false'
cppcoreguidelines-explicit-virtual-functions.IgnoreTemplateInstantiations: 'false'
cppcoreguidelines-explicit-virtual-functions.OverrideSpelling: override
cppcoreguidelines-init-variables.IncludeStyle: llvm
cppcoreguidelines-init-variables.MathHeader: '<math.h>'
cppcoreguidelines-macro-usage.AllowedRegexp: '^DEBUG_*'
cppcoreguidelines-macro-usage.CheckCapsOnly: 'false'
cppcoreguidelines-macro-usage.IgnoreCommandLineMacros: 'true'
cppcoreguidelines-missing-std-forward.ForwardFunction: '::std::forward'
cppcoreguidelines-narrowing-conversions.IgnoreConversionFromTypes: ''
cppcoreguidelines-narrowing-conversions.PedanticMode: 'false'
cppcoreguidelines-narrowing-conversions.WarnOnEquivalentBitWidth: 'true'
cppcoreguidelines-narrowing-conversions.WarnOnFloatingPointNarrowingConversion: 'true'
cppcoreguidelines-narrowing-conversions.WarnOnIntegerNarrowingConversion: 'true'
cppcoreguidelines-narrowing-conversions.WarnOnIntegerToFloatingPointNarrowingConversion: 'true'
cppcoreguidelines-narrowing-conversions.WarnWithinTemplateInstantiation: 'false'
cppcoreguidelines-no-malloc.Allocations: '::malloc;::calloc'
cppcoreguidelines-no-malloc.Deallocations: '::free'
cppcoreguidelines-no-malloc.Reallocations: '::realloc'
cppcoreguidelines-no-suspend-with-lock.LockGuards: '::std::unique_lock;::std::scoped_lock;::std::shared_lock;::std::lock_guard'
cppcoreguidelines-non-private-member-variables-in-classes.IgnoreClassesWithAllMemberVariablesBeingPublic: 'true'
cppcoreguidelines-non-private-member-variables-in-classes.IgnorePublicMemberVariables: 'false'
cppcoreguidelines-owning-memory.LegacyResourceConsumers: '::free;::realloc;::freopen;::fclose'
cppcoreguidelines-owning-memory.LegacyResourceProducers: '::malloc;::aligned_alloc;::realloc;::calloc;::fopen;::freopen;::tmpfile'
cppcoreguidelines-pro-bounds-constant-array-index.GslHeader: ''
cppcoreguidelines-pro-bounds-constant-array-index.IncludeStyle: llvm
cppcoreguidelines-pro-type-const-cast.StrictMode: 'false'
cppcoreguidelines-pro-type-member-init.IgnoreArrays: 'false'
cppcoreguidelines-pro-type-member-init.UseAssignment: 'false'
cppcoreguidelines-pro-type-static-cast-downcast.StrictMode: 'true'
cppcoreguidelines-rvalue-reference-param-not-moved.AllowPartialMove: 'false'
cppcoreguidelines-rvalue-reference-param-not-moved.IgnoreNonDeducedTemplateTypes: 'false'
cppcoreguidelines-rvalue-reference-param-not-moved.IgnoreUnnamedParams: 'false'
cppcoreguidelines-rvalue-reference-param-not-moved.MoveFunction: '::std::move'
cppcoreguidelines-special-member-functions.AllowImplicitlyDeletedCopyOrMove: 'false'
cppcoreguidelines-special-member-functions.AllowMissingMoveFunctions: 'false'
cppcoreguidelines-special-member-functions.AllowMissingMoveFunctionsWhenCopyIsDeleted: 'false'
cppcoreguidelines-special-member-functions.AllowSoleDefaultDtor: 'false'
cppcoreguidelines-special-member-functions.IgnoreMacros: 'true'
cppcoreguidelines-use-default-member-init.IgnoreMacros: 'true'
cppcoreguidelines-use-default-member-init.UseAssignment: 'false'
cppcoreguidelines-use-enum-class.IgnoreUnscopedEnumsInClasses: 'true'
SystemHeaders: false
...
44 changes: 9 additions & 35 deletions etc/run-clang-tidy.sh
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ install_build_tools
export CMAKE_GENERATOR="Ninja"

uv tool install -q clang-tidy
clang-tidy --version
version="$(clang-tidy --version | perl -lne 'print $1 if m|LLVM version (\d+\.\d+\.\d+)|')"
echo "clang-tidy version: ${version:?}"

# Use ccache if available.
if [[ -f "../mongoc/.evergreen/scripts/find-ccache.sh" ]]; then
Expand All @@ -37,41 +38,14 @@ cmake_config_flags=(
)

# Generate the compilation database file.
cmake -S . -B build "${cmake_config_flags[@]}"
cmake "${cmake_config_flags[@]}" -B build

# Some files (i.e. headers) may need to be generated during the build step.
cmake --build build
mapfile -t sources < <(find src -type f \( -name *.cc -o -name *.cpp \) | perl -lne 'print if m$.*/(?:bsoncxx|mongocxx)/lib/.*$')

#
# Each check has a name and the checks to run can be chosen using the -checks= option, which specifies a comma-separated
# list of positive and negative (prefixed with -) globs. For example:
#
# $ clang-tidy test.cpp -checks=-*,clang-analyzer-*,-clang-analyzer-cplusplus*
#
# will disable all default checks (-*) and enable all clang-analyzer-* checks except for clang-analyzer-cplusplus* ones.
#
# The -list-checks option lists all the enabled checks. When used without -checks=, it shows checks enabled by default.
# Use -checks=* to see all available checks or with any other value of -checks= to see which checks are enabled by this
# value.
#
# see https://clang.llvm.org/extra/clang-tidy
#

echo "Running clang-tidy with configuration:"
clang-tidy -p=build -dump-config

find_args=(
-type f
\( -name *.hh -o -name *.hpp -o -name *.cpp \) # All sources including headers.
-not -path "*/third_party/*" # Excluding third party headers.
-not -path "*/config/*.hpp" # Excluding config headers.
-not -path "*bsoncxx/v_noabi/bsoncxx/enums/*.hpp" # Excluding X macro headers.
clang_tidy_flags=(
--quiet
-p build
--header-filter '.*/(?:bsoncxx|mongocxx)/(?:include|lib)/.*'
)

echo "Scanning the following files:"
find src "${find_args[@]}" | sed -E -e 's/^/ - /'

# TODO: update clang-tidy config and address warnings.
{
find src "${find_args[@]}" | parallel clang-tidy --quiet -p=build {} 2>/dev/null
} || true
printf "%s\n" "${sources[@]}" | parallel -q "${parallel_flags[@]}" clang-tidy "${clang_tidy_flags[@]:?}" {} 2>/dev/null
17 changes: 14 additions & 3 deletions src/bsoncxx/lib/bsoncxx/private/itoa.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ namespace bsoncxx {

namespace {

// Precomputed table of C strings.
// NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays)
constexpr char k_index_table[] =
"0\0"
"1\0"
Expand Down Expand Up @@ -1032,17 +1034,25 @@ itoa& itoa::operator=(std::uint32_t new_val) {
return *this;
}

// Index the precomputed table by powers of 10 with additional offsets to account for intermediate null terminators.
// NOLINTBEGIN(cppcoreguidelines-avoid-magic-numbers)
void itoa::_init() {
if (_val < 10u) {
// Index by (single digit + null terminator).
_str = k_index_table + (2u * _val);
_len = 1u;
} else if (_val < 100u) {
_str = k_index_table + (2u * 10u) + (3u * (_val - 10u));
// Index by (double digit + null terminator) and skip lower entries.
_str = k_index_table + (3u * (_val - 10u)) + (2u * 10u);
_len = 2u;
} else if (_val < 1000u) {
_str = k_index_table + (2u * 10u) + (3u * 90u) + (4 * (_val - 100u));
// Index by (triple digit + null terminator) and skip lower entries.
_str = k_index_table + (4u * (_val - 100u)) + (2u * 10u) + (3u * 90u);
_len = 3u;
} else {
}

// Fallback to traditional algorithm.
else {
int size = static_cast<std::int32_t>(sizeof(_buf) - 1u);
int i = size;

Expand All @@ -1058,5 +1068,6 @@ void itoa::_init() {
_len = static_cast<std::uint8_t>(size - i);
}
}
// NOLINTEND(cppcoreguidelines-avoid-magic-numbers)

} // namespace bsoncxx
12 changes: 8 additions & 4 deletions src/bsoncxx/lib/bsoncxx/private/itoa.hh
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,14 @@ namespace bsoncxx {

class itoa {
private:
std::uint32_t _val;
char const* _str;
std::uint8_t _len;
char _buf[11];
// Exact value of UINT32_MAX for `sizeof()` below.
// NOLINTNEXTLINE(cppcoreguidelines-avoid-magic-numbers).
static_assert(UINT32_MAX == std::uint32_t{4294967295}, "");

std::uint32_t _val = {};
char const* _str = {};
std::uint8_t _len = {};
char _buf[sizeof("4294967295")] = {};

public:
~itoa() = default;
Expand Down
2 changes: 1 addition & 1 deletion src/bsoncxx/lib/bsoncxx/private/version.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ std::vector<int> split_version(bsoncxx::stdx::string_view input) {

std::vector<int> ret;

std::size_t pos;
std::size_t pos = {};

while ((pos = input.find_first_not_of(digits)) != npos) {
auto const str = input.substr(0u, pos);
Expand Down
7 changes: 4 additions & 3 deletions src/bsoncxx/lib/bsoncxx/v1/decimal128.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include <bsoncxx/v1/exception.hpp>
#include <bsoncxx/v1/stdx/string_view.hpp>

#include <array>
#include <climits>
#include <cstddef>
#include <string>
Expand Down Expand Up @@ -59,9 +60,9 @@ std::string decimal128::to_string() const {
bson_decimal128_t d128;
d128.high = _high;
d128.low = _low;
char str[BSON_DECIMAL128_STRING];
bson_decimal128_to_string(&d128, str);
return {str};
std::array<char, BSON_DECIMAL128_STRING> str = {};
bson_decimal128_to_string(&d128, str.data());
return {str.data()};
}

std::error_category const& decimal128::error_category() {
Expand Down
12 changes: 11 additions & 1 deletion src/bsoncxx/lib/bsoncxx/v1/element/view.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,8 @@ class alignas(BSONCXX_PRIVATE_MAX_ALIGN_T) view::impl {
throw v1::exception{code::invalid_data};
}

// Helpers to access the inline PIMPL object.
// NOLINTBEGIN(cppcoreguidelines-pro-type-reinterpret-cast)
static impl const& with(view const& v) {
return *reinterpret_cast<view::impl const*>(v._storage.data());
}
Expand All @@ -167,6 +169,7 @@ class alignas(BSONCXX_PRIVATE_MAX_ALIGN_T) view::impl {
static impl* with(view* v) {
return reinterpret_cast<view::impl*>(v->_storage.data());
}
// NOLINTEND(cppcoreguidelines-pro-type-reinterpret-cast)
};

void view::impl::check() const {
Expand All @@ -192,19 +195,26 @@ void view::impl::check() const {

view::~view() = default;

// _storage: initialized with placement new.
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init)
view::view(view const& other) noexcept {
new (impl::with(this)) impl{impl::with(other)};
new (_storage.data()) impl{impl::with(other)};
}

// NOLINTNEXTLINE(cert-oop54-cpp): handled by impl.
view& view::operator=(view const& other) noexcept {
*impl::with(this) = impl::with(other);
return *this;
}

// _storage: initialized with placement new.
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init)
view::view() {
new (_storage.data()) impl{};
}

// _storage: initialized with placement new.
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init)
view::view(impl i) {
new (_storage.data()) impl{i};
}
Expand Down
13 changes: 10 additions & 3 deletions src/bsoncxx/lib/bsoncxx/v1/oid.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include <bsoncxx/v1/exception.hpp>
#include <bsoncxx/v1/stdx/string_view.hpp>

#include <array>
#include <cstdint>
#include <cstring>
#include <ctime>
Expand All @@ -37,6 +38,8 @@ using code = v1::oid::errc;
static_assert(is_regular<oid>::value, "bsoncxx::v1::oid must be regular");
static_assert(is_semitrivial<oid>::value, "bsoncxx::v1::oid must be semitrivial");

// _bytes: initialized with memcpy.
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init)
oid::oid() {
#if defined(_WIN32)
// Ensure the Winsock DLL is initialized prior to calling `gethostname` in `bsoncxx::v1::oid::oid()`:
Expand Down Expand Up @@ -66,6 +69,8 @@ oid::oid() {
std::memcpy(_bytes.data(), oid.bytes, sizeof(oid.bytes));
}

// _bytes: initialized with memcpy.
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init)
oid::oid(std::uint8_t const* bytes, std::size_t len) {
if (!bytes) {
throw v1::exception{code::null_bytes_ptr};
Expand All @@ -78,6 +83,8 @@ oid::oid(std::uint8_t const* bytes, std::size_t len) {
std::memcpy(_bytes.data(), bytes, _bytes.size());
}

// _bytes: initialized with memcpy.
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init)
oid::oid(v1::stdx::string_view str) {
if (str.empty()) {
throw v1::exception{code::empty_string};
Expand All @@ -95,9 +102,9 @@ oid::oid(v1::stdx::string_view str) {
std::string oid::to_string() const {
bson_oid_t oid;
std::memcpy(oid.bytes, _bytes.data(), sizeof(oid.bytes));
char str[25];
bson_oid_to_string(&oid, str);
return std::string(str);
std::array<char, 2u * k_oid_length + 1u> str = {}; // Two hex digits per byte + null terminator: 25 characters.
bson_oid_to_string(&oid, str.data());
return std::string(str.data());
}

std::time_t oid::get_time_t() const {
Expand Down
Loading