Skip to content
Open
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
3 changes: 3 additions & 0 deletions include/boost/openmethod/core.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2939,6 +2939,9 @@ typename method<Id, ReturnType(Parameters...), Registry>::FunctionPointer
template<
typename Id, typename... Parameters, typename ReturnType, class Registry>
method<Id, ReturnType(Parameters...), Registry>
// The constructor uses only zero- or constant-initialized statics, so the
// order of initialization does not matter.
// coverity[global_init_order]
method<Id, ReturnType(Parameters...), Registry>::fn;

template<
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,9 @@ struct default_error_handler : error_handler {
//! @param error The error object.
template<class Error>
static auto error(const Error& error) -> void {
// Copy on purpose: the handler may call set(), which would destroy
// the function object while it is running.
// coverity[auto_causes_copy]
auto handler = st().handler ? st().handler : default_handler;
handler(error_variant(error));
}
Expand All @@ -119,7 +122,11 @@ struct default_error_handler : error_handler {
static auto set(function_type new_handler) -> function_type {
auto prev = std::exchange(st().handler, std::move(new_handler));

return prev ? prev : default_handler;
if (!prev) {
return default_handler;
}

return prev;
}

//! The default error handler function.
Expand Down
6 changes: 3 additions & 3 deletions include/boost/openmethod/policies/minimal_cover_hash.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -405,7 +405,7 @@ auto minimal_cover_hash<MaxBits>::fn<Registry>::minimal_cover(
std::uint64_t by_add = 0;

while (!injective(ids, by_add, scratch)) {
int best_bit = -1;
std::uint64_t best_bit = 0;
std::size_t best_count = (std::numeric_limits<std::size_t>::max)();

for (const auto& info : bits) {
Expand All @@ -419,11 +419,11 @@ auto minimal_cover_hash<MaxBits>::fn<Registry>::minimal_cover(

if (count < best_count) {
best_count = count;
best_bit = info.bit;
best_bit = bit;
}
}

by_add |= std::uint64_t(1) << best_bit;
by_add |= best_bit;
}

by_add = drop(by_add);
Expand Down
3 changes: 3 additions & 0 deletions include/boost/openmethod/preamble.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,9 @@ struct class_info : static_list<class_info>::static_link {
}

auto type_id_end() const {
// One past the end of a one-element range: a valid pointer, never
// dereferenced.
// coverity[array_vs_singleton]
return &type + 1;
}
};
Expand Down
14 changes: 11 additions & 3 deletions test/Jamfile
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

import-search /boost/config/checks ;

import os ;
import testing ;
import config : requires ;

Expand Down Expand Up @@ -107,10 +108,17 @@ for local src in $(bmi2-sources)
run mix_release_debug/main.cpp mix_release_debug/lib.cpp unit_test_framework ;


for local src in [ glob compile_fail_*.cpp
../doc/modules/ROOT/examples/troubleshooting/compile_fail_*.cpp ]
# Boost.CI sets COVERITY_SCAN_TOKEN only in its Coverity step. These sources
# are meant not to compile; Coverity analyzes the half-parsed translation unit
# and reports defects (a missing return, an uncaught exception) that are not
# in the code.
if ! [ os.environ COVERITY_SCAN_TOKEN ]
{
compile-fail $(src) ;
for local src in [ glob compile_fail_*.cpp
../doc/modules/ROOT/examples/troubleshooting/compile_fail_*.cpp ]
{
compile-fail $(src) ;
}
}

build-project dynamic_loading ;
Expand Down
2 changes: 1 addition & 1 deletion test/dynamic_loading/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ BOOST_OPENMETHOD_TEST_CLASSES(Animal, Dog, Cat);

boost::filesystem::path find_lib(
const boost::filesystem::path& dir, const char* name_fragment) {
for (auto entry : boost::filesystem::directory_iterator(dir)) {
for (const auto& entry : boost::filesystem::directory_iterator(dir)) {
auto fname = entry.path().filename().string();
if (fname.find(name_fragment) != std::string::npos) {
return entry.path();
Expand Down
3 changes: 3 additions & 0 deletions test/test_dispatch_boost_any.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -197,17 +197,20 @@ BOOST_AUTO_TEST_CASE(boost_any_by_xvalue_ref) {
boost::any spot(Dog{"Spot"});
BOOST_TEST(steal(std::move(spot)) == "Spot the dog");
// the overrider moved the name out; the `any` still owns the Dog
// coverity[use_after_move]
BOOST_TEST(!spot.empty());
BOOST_TEST(boost::any_cast<const Dog&>(spot).name == "");

boost::any felix(std::string{"Felix the cat"});
BOOST_TEST(steal(std::move(felix)) == "Felix the cat");
// coverity[use_after_move]
BOOST_TEST(!felix.empty());
BOOST_TEST(boost::any_cast<const std::string&>(felix) == "");

// moving an int copies it
boost::any answer(42);
BOOST_TEST(steal(std::move(answer)) == "42 the integer");
// coverity[use_after_move]
BOOST_TEST(boost::any_cast<const int&>(answer) == 42);
}
} // namespace BOOST_OPENMETHOD_GENSYM
Expand Down
3 changes: 3 additions & 0 deletions test/test_dispatch_std_any.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -213,17 +213,20 @@ BOOST_AUTO_TEST_CASE(std_any_by_xvalue_ref) {
std::any spot(Dog{"Spot"});
BOOST_TEST(steal(std::move(spot)) == "Spot the dog");
// the overrider moved the name out; the `any` still owns the Dog
// coverity[use_after_move]
BOOST_TEST(spot.has_value());
BOOST_TEST(std::any_cast<const Dog&>(spot).name == "");

std::any felix(std::string{"Felix the cat"});
BOOST_TEST(steal(std::move(felix)) == "Felix the cat");
// coverity[use_after_move]
BOOST_TEST(felix.has_value());
BOOST_TEST(std::any_cast<const std::string&>(felix) == "");

// moving an int copies it
std::any answer(42);
BOOST_TEST(steal(std::move(answer)) == "42 the integer");
// coverity[use_after_move]
BOOST_TEST(std::any_cast<const int&>(answer) == 42);
}
} // namespace BOOST_OPENMETHOD_GENSYM
Expand Down
2 changes: 2 additions & 0 deletions test/test_dispatch_type_erasure.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -173,11 +173,13 @@ BOOST_AUTO_TEST_CASE(type_erasure_by_xvalue_ref) {
erased spot(Dog{"Spot"});
BOOST_TEST(steal(std::move(spot)) == "Spot the dog");
// the overrider moved the name out; the `any` still owns the Dog
// coverity[use_after_move]
BOOST_TEST(!te::is_empty(spot));
BOOST_TEST(te::any_cast<const Dog&>(spot).name == "");

erased felix(std::string{"Felix the cat"});
BOOST_TEST(steal(std::move(felix)) == "Felix the cat");
// coverity[use_after_move]
BOOST_TEST(te::any_cast<const std::string&>(felix) == "");
}
} // namespace BOOST_OPENMETHOD_GENSYM
Expand Down
2 changes: 2 additions & 0 deletions test/test_shared_virtual_ptr_value_semantics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,8 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(
// shared_virtual_ptr<Dog>(shared_virtual_ptr<Dog>&)
auto snoopy = std::make_shared<Dog>();
shared_virtual_ptr<Dog, Registry> p(snoopy);
// The copy is the point: this tests the non-const lvalue overload.
// coverity[copy_instead_of_move]
shared_virtual_ptr<Dog, Registry> q(p);
BOOST_TEST(q.get() == snoopy.get());
BOOST_TEST(q.vptr() == Registry::template static_vptr<Dog>);
Expand Down
4 changes: 2 additions & 2 deletions test/test_slot_allocator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ auto str(const Container<T>& container) {

template<typename... Ts>
auto sstr(Ts... args) {
std::vector<class_*> vec{args...};
std::vector<class_*> vec{std::move(args)...};
std::sort(vec.begin(), vec.end());

return str(vec);
Expand Down Expand Up @@ -360,7 +360,7 @@ auto sampled_orders(std::size_t n, std::size_t samples) -> std::vector<order> {
std::vector<order> orders{listed};
orders.emplace_back(listed.rbegin(), listed.rend());
std::mt19937 rng(20250510u);
auto shuffled = listed;
auto shuffled = std::move(listed);

while (samples--) {
for (auto i = shuffled.size(); i > 1; --i) {
Expand Down
2 changes: 2 additions & 0 deletions test/test_smart_virtual_ptr_value_semantics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,8 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(
// dog_virtual_ptr(dog_virtual_ptr&)
auto snoopy = smart::template make<Dog>();
dog_virtual_ptr p(snoopy);
// The copy is the point: this tests the non-const lvalue overload.
// coverity[copy_instead_of_move]
dog_virtual_ptr q(p);
BOOST_TEST(q.get() == snoopy.get());
BOOST_TEST(q.vptr() == default_registry::template static_vptr<Dog>);
Expand Down
2 changes: 2 additions & 0 deletions test/test_virtual_any_type_erasure.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@ BOOST_AUTO_TEST_CASE(virtual_any_by_xvalue_ref) {
virtual_erased spot = Dog{"Spot"};
BOOST_TEST(steal(std::move(spot)) == "Spot the dog");
// the overrider moved the name out; the virtual_any still owns the Dog
// coverity[use_after_move]
BOOST_TEST(!te::is_empty(spot.get()));
BOOST_TEST(te::any_cast<const Dog&>(spot.get()).name == "");

Expand Down Expand Up @@ -203,6 +204,7 @@ BOOST_AUTO_TEST_CASE(virtual_any_value_semantics) {
// move: the source's v-table pointer is nulled
auto moved = std::move(copy);
BOOST_TEST(moved.vptr() == default_registry::static_vptr<Dog>);
// coverity[use_after_move]
BOOST_TEST(copy.vptr() == nullptr);
BOOST_TEST(name(moved) == "Rex the dog");

Expand Down
4 changes: 3 additions & 1 deletion test/test_virtual_ptr_value_semantics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,8 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(
// virtual_ptr<Dog>(virtual_ptr<Dog>&)
Dog snoopy;
virtual_ptr<Dog, Registry> p(snoopy);
// The copy is the point: this tests the non-const lvalue overload.
// coverity[copy_instead_of_move]
virtual_ptr<Dog, Registry> q(p);
BOOST_TEST(q.get() == &snoopy);
BOOST_TEST(q.vptr() == Registry::template static_vptr<Dog>);
Expand All @@ -166,9 +168,9 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(
Dog snoopy;
virtual_ptr<Dog, Registry> p(snoopy);
virtual_ptr<Dog, Registry> q(std::move(p));
// coverity[use_after_move]
BOOST_TEST(q.get() == &snoopy);
BOOST_TEST(q.vptr() == Registry::template static_vptr<Dog>);
// coverity[use_after_move]
BOOST_TEST(p.get() == &snoopy);
BOOST_TEST(p.vptr() == Registry::template static_vptr<Dog>);
}
Expand Down
3 changes: 3 additions & 0 deletions test/test_weak_virtual_ptr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,7 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(
weak_virtual_ptr<Dog, Registry> moved(std::move(source));
BOOST_TEST(moved.lock().get() == snoopy.get());
BOOST_TEST(moved.vptr() == Registry::template static_vptr<Dog>);
// coverity[use_after_move]
BOOST_TEST(source.expired());
BOOST_TEST(source.vptr() == nullptr);
}
Expand All @@ -274,6 +275,7 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(
weak_virtual_ptr<Animal, Registry> moved(std::move(source));
BOOST_TEST(moved.lock().get() == snoopy.get());
BOOST_TEST(moved.vptr() == Registry::template static_vptr<Dog>);
// coverity[use_after_move]
BOOST_TEST(source.expired());
BOOST_TEST(source.vptr() == nullptr);
}
Expand All @@ -284,6 +286,7 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(
moved = std::move(source);
BOOST_TEST(moved.lock().get() == snoopy.get());
BOOST_TEST(moved.vptr() == Registry::template static_vptr<Dog>);
// coverity[use_after_move]
BOOST_TEST(source.expired());
BOOST_TEST(source.vptr() == nullptr);
}
Expand Down
Loading