Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix some clang static analyzer warnings #6675

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

### Fixed
* <How do the end-user experience this issue? what was the impact?> ([#????](https://github.com/realm/realm-core/issues/????), since v?.?.?)
* None.
* Fix some clang static analyzer warnings. None of them were actual bugs ([PR #6675](https://github.com/realm/realm-core/pull/6675)).

### Breaking changes
* None.
Expand Down
8 changes: 4 additions & 4 deletions src/realm/bplustree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -742,9 +742,9 @@ void BPlusTreeBase::bptree_erase(size_t n, BPlusTreeNode::EraseFunc func)
ref_type new_root_ref = node->clear_first_bp_node_ref();
node->destroy_deep();

auto new_root = create_root_from_ref(new_root_ref);

replace_root(std::move(new_root));
if (auto new_root = create_root_from_ref(new_root_ref)) {
replace_root(std::move(new_root));
}
root_size = m_root->get_node_size();
}
}
Expand All @@ -757,7 +757,7 @@ std::unique_ptr<BPlusTreeNode> BPlusTreeBase::create_root_from_ref(ref_type ref)

if (reuse_root) {
m_root->init_from_ref(ref);
return std::move(m_root);
return nullptr;
}

if (is_leaf) {
Expand Down
20 changes: 13 additions & 7 deletions src/realm/bplustree.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -172,10 +172,10 @@ class BPlusTreeBase {

void init_from_ref(ref_type ref)
{
auto new_root = create_root_from_ref(ref);
new_root->bp_set_parent(m_parent, m_ndx_in_parent);

m_root = std::move(new_root);
if (auto new_root = create_root_from_ref(ref)) {
new_root->bp_set_parent(m_parent, m_ndx_in_parent);
m_root = std::move(new_root);
}

invalidate_leaf_cache();
m_size = m_root->get_tree_size();
Expand All @@ -187,9 +187,10 @@ class BPlusTreeBase {
if (!ref) {
return false;
}
auto new_root = create_root_from_ref(ref);
new_root->bp_set_parent(m_parent, m_ndx_in_parent);
m_root = std::move(new_root);
if (auto new_root = create_root_from_ref(ref)) {
new_root->bp_set_parent(m_parent, m_ndx_in_parent);
m_root = std::move(new_root);
}
invalidate_leaf_cache();
m_size = m_root->get_tree_size();
return true;
Expand Down Expand Up @@ -374,6 +375,11 @@ class BPlusTree : public BPlusTreeBase {
REALM_NOINLINE T get_uncached(size_t n) const
{
T value;
#ifdef __clang_analyzer__
// Clang's static analyzer can't see that value will always be initialized
// inside bptree_access()
value = {};
#endif

auto func = [&value](BPlusTreeNode* node, size_t ndx) {
LeafNode* leaf = static_cast<LeafNode*>(node);
Expand Down
3 changes: 2 additions & 1 deletion src/realm/object-store/c_api/realm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,8 @@ RLM_API bool realm_remove_table(realm_t* realm, const char* table_name, bool* ta
"Attempt to remove a table that is currently part of the schema");
}
(*realm)->read_group().remove_table(table->get_key());
*table_deleted = true;
if (table_deleted)
*table_deleted = true;
}
return true;
});
Expand Down
4 changes: 3 additions & 1 deletion src/realm/sync/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,10 @@ set(NOINST_HEADERS
noinst/sync_metadata_schema.hpp
)

set(SYNC_HEADERS ${IMPL_INSTALL_HEADESR}
set(SYNC_HEADERS
${IMPL_INSTALL_HEADESR}
${SYNC_INSTALL_HEADERS}
${SYNC_NETWORK_INSTALL_HEADERS}
${NOINST_HEADERS})

add_library(Sync STATIC ${SYNC_SOURCES} ${SYNC_HEADERS})
Expand Down
56 changes: 28 additions & 28 deletions src/realm/sync/network/network.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1998,7 +1998,7 @@ class Service::PostOper : public PostOperBase {
public:
PostOper(std::size_t size, Impl& service, H&& handler)
: PostOperBase{size, service}
, m_handler{std::move(handler)}
, m_handler{std::forward<H>(handler)}
{
}
void recycle_and_execute() override final
Expand Down Expand Up @@ -2256,7 +2256,7 @@ class Service::BasicStreamOps {
char* begin = buffer;
char* end = buffer + size;
LendersReadOperPtr op = Service::alloc<ReadOper<H>>(stream.lowest_layer().m_read_oper, stream, is_read_some,
begin, end, std::move(handler)); // Throws
begin, end, std::forward<H>(handler)); // Throws
stream.lowest_layer().m_desc.initiate_oper(std::move(op)); // Throws
}

Expand All @@ -2265,8 +2265,9 @@ class Service::BasicStreamOps {
{
const char* begin = data;
const char* end = data + size;
LendersWriteOperPtr op = Service::alloc<WriteOper<H>>(
stream.lowest_layer().m_write_oper, stream, is_write_some, begin, end, std::move(handler)); // Throws
LendersWriteOperPtr op =
Service::alloc<WriteOper<H>>(stream.lowest_layer().m_write_oper, stream, is_write_some, begin, end,
std::forward<H>(handler)); // Throws
stream.lowest_layer().m_desc.initiate_oper(std::move(op)); // Throws
}

Expand All @@ -2278,7 +2279,7 @@ class Service::BasicStreamOps {
char* end = buffer + size;
LendersBufferedReadOperPtr op =
Service::alloc<BufferedReadOper<H>>(stream.lowest_layer().m_read_oper, stream, begin, end, delim, rab,
std::move(handler)); // Throws
std::forward<H>(handler)); // Throws
stream.lowest_layer().m_desc.initiate_oper(std::move(op)); // Throws
}
};
Expand Down Expand Up @@ -2554,7 +2555,7 @@ class Service::BasicStreamOps<S>::ReadOper : public ReadOperBase {
public:
ReadOper(std::size_t size, S& stream, bool is_read_some, char* begin, char* end, H&& handler)
: ReadOperBase{size, stream, is_read_some, begin, end}
, m_handler{std::move(handler)}
, m_handler{std::forward<H>(handler)}
{
}
void recycle_and_execute() override final
Expand Down Expand Up @@ -2584,7 +2585,7 @@ class Service::BasicStreamOps<S>::WriteOper : public WriteOperBase {
public:
WriteOper(std::size_t size, S& stream, bool is_write_some, const char* begin, const char* end, H&& handler)
: WriteOperBase{size, stream, is_write_some, begin, end}
, m_handler{std::move(handler)}
, m_handler{std::forward<H>(handler)}
{
}
void recycle_and_execute() override final
Expand Down Expand Up @@ -2615,7 +2616,7 @@ class Service::BasicStreamOps<S>::BufferedReadOper : public BufferedReadOperBase
BufferedReadOper(std::size_t size, S& stream, char* begin, char* end, int delim, ReadAheadBuffer& rab,
H&& handler)
: BufferedReadOperBase{size, stream, begin, end, delim, rab}
, m_handler{std::move(handler)}
, m_handler{std::forward<H>(handler)}
{
}
void recycle_and_execute() override final
Expand Down Expand Up @@ -2703,7 +2704,7 @@ template <class H>
inline Service::PostOperBase* Service::post_oper_constr(void* addr, std::size_t size, Impl& service, void* cookie)
{
H& handler = *static_cast<H*>(cookie);
return new (addr) PostOper<H>(size, service, std::move(handler)); // Throws
return new (addr) PostOper<H>(size, service, std::forward<H>(handler)); // Throws
}

inline bool Service::AsyncOper::in_use() const noexcept
Expand Down Expand Up @@ -2769,10 +2770,8 @@ inline void Service::AsyncOper::do_recycle_and_execute(bool orphaned, H& handler
// happens. For that reason, copying and moving of arguments must not
// happen until we are in a scope (this scope) that catches and deals
// correctly with such exceptions.
do_recycle_and_execute_helper(orphaned, was_recycled, std::move(handler),
do_recycle_and_execute_helper(orphaned, was_recycled, std::forward<H>(handler),
std::forward<Args>(args)...); // Throws

// Removed catch to prevent truncating the stack trace on exception
}

template <class H, class... Args>
Expand Down Expand Up @@ -2805,7 +2804,7 @@ class Resolver::ResolveOper : public Service::ResolveOperBase {
public:
ResolveOper(std::size_t size, Resolver& r, Query q, H&& handler)
: ResolveOperBase{size, r, std::move(q)}
, m_handler{std::move(handler)}
, m_handler{std::forward<H>(handler)}
{
}
void recycle_and_execute() override final
Expand Down Expand Up @@ -2847,7 +2846,7 @@ template <class H>
void Resolver::async_resolve(Query query, H&& handler)
{
Service::LendersResolveOperPtr op = Service::alloc<ResolveOper<H>>(m_resolve_oper, *this, std::move(query),
std::move(handler)); // Throws
std::forward<H>(handler)); // Throws
initiate_oper(std::move(op)); // Throws
}

Expand Down Expand Up @@ -3086,7 +3085,7 @@ class Socket::ConnectOper : public ConnectOperBase {
public:
ConnectOper(std::size_t size, Socket& sock, H&& handler)
: ConnectOperBase{size, sock}
, m_handler{std::move(handler)}
, m_handler{std::forward<H>(handler)}
{
}
void recycle_and_execute() override final
Expand Down Expand Up @@ -3214,50 +3213,51 @@ inline std::size_t Socket::write_some(const char* data, std::size_t size, std::e
template <class H>
inline void Socket::async_connect(const Endpoint& ep, H&& handler)
{
LendersConnectOperPtr op = Service::alloc<ConnectOper<H>>(m_write_oper, *this, std::move(handler)); // Throws
LendersConnectOperPtr op =
Service::alloc<ConnectOper<H>>(m_write_oper, *this, std::forward<H>(handler)); // Throws
m_desc.initiate_oper(std::move(op), ep); // Throws
}

template <class H>
inline void Socket::async_read(char* buffer, std::size_t size, H&& handler)
{
bool is_read_some = false;
StreamOps::async_read(*this, buffer, size, is_read_some, std::move(handler)); // Throws
StreamOps::async_read(*this, buffer, size, is_read_some, std::forward<H>(handler)); // Throws
}

template <class H>
inline void Socket::async_read(char* buffer, std::size_t size, ReadAheadBuffer& rab, H&& handler)
{
int delim = std::char_traits<char>::eof();
StreamOps::async_buffered_read(*this, buffer, size, delim, rab, std::move(handler)); // Throws
StreamOps::async_buffered_read(*this, buffer, size, delim, rab, std::forward<H>(handler)); // Throws
}

template <class H>
inline void Socket::async_read_until(char* buffer, std::size_t size, char delim, ReadAheadBuffer& rab, H&& handler)
{
int delim_2 = std::char_traits<char>::to_int_type(delim);
StreamOps::async_buffered_read(*this, buffer, size, delim_2, rab, std::move(handler)); // Throws
StreamOps::async_buffered_read(*this, buffer, size, delim_2, rab, std::forward<H>(handler)); // Throws
}

template <class H>
inline void Socket::async_write(const char* data, std::size_t size, H&& handler)
{
bool is_write_some = false;
StreamOps::async_write(*this, data, size, is_write_some, std::move(handler)); // Throws
StreamOps::async_write(*this, data, size, is_write_some, std::forward<H>(handler)); // Throws
}

template <class H>
inline void Socket::async_read_some(char* buffer, std::size_t size, H&& handler)
{
bool is_read_some = true;
StreamOps::async_read(*this, buffer, size, is_read_some, std::move(handler)); // Throws
StreamOps::async_read(*this, buffer, size, is_read_some, std::forward<H>(handler)); // Throws
}

template <class H>
inline void Socket::async_write_some(const char* data, std::size_t size, H&& handler)
{
bool is_write_some = true;
StreamOps::async_write(*this, data, size, is_write_some, std::move(handler)); // Throws
StreamOps::async_write(*this, data, size, is_write_some, std::forward<H>(handler)); // Throws
}

inline void Socket::shutdown(shutdown_type what)
Expand Down Expand Up @@ -3394,7 +3394,7 @@ class Acceptor::AcceptOper : public AcceptOperBase {
public:
AcceptOper(std::size_t size, Acceptor& a, Socket& s, Endpoint* e, H&& handler)
: AcceptOperBase{size, a, s, e}
, m_handler{std::move(handler)}
, m_handler{std::forward<H>(handler)}
{
}
void recycle_and_execute() override final
Expand Down Expand Up @@ -3456,13 +3456,13 @@ template <class H>
inline void Acceptor::async_accept(Socket& sock, H&& handler)
{
Endpoint* ep = nullptr;
async_accept(sock, ep, std::move(handler)); // Throws
async_accept(sock, ep, std::forward<H>(handler)); // Throws
}

template <class H>
inline void Acceptor::async_accept(Socket& sock, Endpoint& ep, H&& handler)
{
async_accept(sock, &ep, std::move(handler)); // Throws
async_accept(sock, &ep, std::forward<H>(handler)); // Throws
}

inline std::error_code Acceptor::accept(Socket& socket, Endpoint* ep, std::error_code& ec)
Expand Down Expand Up @@ -3491,7 +3491,7 @@ inline void Acceptor::async_accept(Socket& sock, Endpoint* ep, H&& handler)
if (REALM_UNLIKELY(sock.is_open()))
throw util::runtime_error("Socket is already open");
LendersAcceptOperPtr op = Service::alloc<AcceptOper<H>>(m_read_oper, *this, sock, ep,
std::move(handler)); // Throws
std::forward<H>(handler)); // Throws
m_desc.initiate_oper(std::move(op)); // Throws
}

Expand All @@ -3502,7 +3502,7 @@ class DeadlineTimer::WaitOper : public Service::WaitOperBase {
public:
WaitOper(std::size_t size, DeadlineTimer& timer, clock::time_point expiration_time, H&& handler)
: Service::WaitOperBase{size, timer, expiration_time}
, m_handler{std::move(handler)}
, m_handler{std::forward<H>(handler)}
{
}
void recycle_and_execute() override final
Expand Down Expand Up @@ -3542,7 +3542,7 @@ inline void DeadlineTimer::async_wait(std::chrono::duration<R, P> delay, H&& han
throw util::overflow_error("Expiration time overflow");
clock::time_point expiration_time = now + delay;
initiate_oper(Service::alloc<WaitOper<H>>(m_wait_oper, *this, expiration_time,
std::move(handler))); // Throws
std::forward<H>(handler))); // Throws
}

// ---------------- ReadAheadBuffer ----------------
Expand Down
14 changes: 8 additions & 6 deletions src/realm/table.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -560,6 +560,7 @@ void Table::remove_recursive(CascadeState& cascade_state)
REALM_ASSERT(group);
cascade_state.m_group = group;

std::vector<std::pair<TableKey, ObjKey>> to_delete;
do {
cascade_state.send_notifications();

Expand All @@ -572,14 +573,15 @@ void Table::remove_recursive(CascadeState& cascade_state)
}
cascade_state.m_to_be_nullified.clear();

auto to_delete = std::move(cascade_state.m_to_be_deleted);
for (auto obj : to_delete) {
auto table = group->get_table(obj.first);
to_delete.swap(cascade_state.m_to_be_deleted);
for (auto [table_key, obj_key] : to_delete) {
auto table = group->get_table(table_key);
// This might add to the list of objects that should be deleted
REALM_ASSERT(!obj.second.is_unresolved());
table->m_clusters.erase(obj.second, cascade_state);
REALM_ASSERT(!obj_key.is_unresolved());
table->m_clusters.erase(obj_key, cascade_state);
}
nullify_links(cascade_state);
to_delete.clear();
} while (!cascade_state.m_to_be_deleted.empty() || !cascade_state.m_to_be_nullified.empty());
}

Expand Down Expand Up @@ -1679,7 +1681,7 @@ void copy_list<Timestamp>(ref_type sub_table_ref, Obj& obj, ColKey col, Allocato

void Table::create_columns()
{
size_t cnt;
size_t cnt = 0;
auto get_column_cnt = [&cnt](const Cluster* cluster) {
cnt = cluster->nb_columns();
return IteratorControl::Stop;
Expand Down
3 changes: 3 additions & 0 deletions src/realm/util/thread.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -557,6 +557,7 @@ inline void Mutex::unlock() noexcept
#else
int r = pthread_mutex_unlock(&m_impl);
REALM_ASSERT(r == 0);
static_cast<void>(r);
#endif
}

Expand Down Expand Up @@ -780,6 +781,7 @@ inline void CondVar::notify() noexcept
#else
int r = pthread_cond_signal(&m_impl);
REALM_ASSERT(r == 0);
static_cast<void>(r);
#endif
}

Expand All @@ -790,6 +792,7 @@ inline void CondVar::notify_all() noexcept
#else
int r = pthread_cond_broadcast(&m_impl);
REALM_ASSERT(r == 0);
static_cast<void>(r);
#endif
}

Expand Down
Loading