diff --git a/libuavcan/include/uavcan/dynamic_memory.hpp b/libuavcan/include/uavcan/dynamic_memory.hpp index fc5c977151..7bec0f66cb 100644 --- a/libuavcan/include/uavcan/dynamic_memory.hpp +++ b/libuavcan/include/uavcan/dynamic_memory.hpp @@ -23,7 +23,9 @@ class UAVCAN_EXPORT IPoolAllocator public: virtual ~IPoolAllocator() { } + // coverity[+alloc] virtual void* allocate(std::size_t size) = 0; + // coverity[+free : arg-0] virtual void deallocate(const void* ptr) = 0; virtual bool isInPool(const void* ptr) const = 0; @@ -53,7 +55,9 @@ public: bool addPool(IPoolAllocator* pool); + // coverity[+alloc] void* allocate(std::size_t size); + // coverity[+free : arg-0] void deallocate(const void* ptr); bool isInPool(const void* ptr) const; @@ -86,7 +90,9 @@ public: PoolAllocator(); + // coverity[+alloc] void* allocate(std::size_t size); + // coverity[+free : arg-0] void deallocate(const void* ptr); bool isInPool(const void* ptr) const; @@ -114,7 +120,9 @@ public: assert(max_blocks_ > 0); } + // coverity[+alloc] void* allocate(std::size_t size); + // coverity[+free : arg-0] void deallocate(const void* ptr); bool isInPool(const void* ptr) const; @@ -232,6 +240,7 @@ PoolAllocator::PoolAllocator() std::memset(pool_.bytes, 0, PoolSize); for (unsigned i = 0; (i + 1) < (NumBlocks - 1 + 1); i++) // -Werror=type-limits { + // coverity[dead_error_line : FALSE] free_list_[i].next = free_list_ + i + 1; } free_list_[NumBlocks - 1].next = NULL; diff --git a/libuavcan/include/uavcan/error.hpp b/libuavcan/include/uavcan/error.hpp index 8411b32efc..17634cadac 100644 --- a/libuavcan/include/uavcan/error.hpp +++ b/libuavcan/include/uavcan/error.hpp @@ -36,6 +36,7 @@ enum __attribute__ ((noreturn)) #endif UAVCAN_EXPORT +// coverity[+kill] void handleFatalError(const char* msg); } diff --git a/libuavcan/include/uavcan/marshal/array.hpp b/libuavcan/include/uavcan/marshal/array.hpp index 03433bbd44..dd6a2c3942 100644 --- a/libuavcan/include/uavcan/marshal/array.hpp +++ b/libuavcan/include/uavcan/marshal/array.hpp @@ -360,6 +360,7 @@ class UAVCAN_EXPORT Array : public ArrayImpl #if UAVCAN_CPP_VERSION >= UAVCAN_CPP11 const bool nan = std::isnan(*it); #else + // coverity[same_on_both_sides : FALSE] const bool nan = (*it) != (*it); #endif if (!nan) diff --git a/libuavcan/include/uavcan/marshal/integer_spec.hpp b/libuavcan/include/uavcan/marshal/integer_spec.hpp index 172f51e542..dea500a3e5 100644 --- a/libuavcan/include/uavcan/marshal/integer_spec.hpp +++ b/libuavcan/include/uavcan/marshal/integer_spec.hpp @@ -78,7 +78,9 @@ private: static void validate() { StaticAssert<(BitLen <= (sizeof(StorageType) * 8))>::check(); + // coverity[result_independent_of_operands : FALSE] assert(max() <= std::numeric_limits::max()); + // coverity[result_independent_of_operands : FALSE] assert(min() >= std::numeric_limits::min()); } diff --git a/libuavcan/tools/coverity_scan_model.cpp b/libuavcan/tools/coverity_scan_model.cpp new file mode 100644 index 0000000000..e66bb785fa --- /dev/null +++ b/libuavcan/tools/coverity_scan_model.cpp @@ -0,0 +1,45 @@ +/* + * Coverity Scan model. + * + * - A model file can't import any header files. + * - Therefore only some built-in primitives like int, char and void are + * available but not wchar_t, NULL etc. + * - Modeling doesn't need full structs and typedefs. Rudimentary structs + * and similar types are sufficient. + * - An uninitialized local pointer is not an error. It signifies that the + * variable could be either NULL or have some data. + * + * Coverity Scan doesn't pick up modifications automatically. The model file + * must be uploaded by an admin in the analysis settings of + * https://scan.coverity.com/projects/1513 + */ + +namespace std +{ + typedef unsigned long size_t; +} + +namespace uavcan +{ + +void handleFatalError(const char* msg) +{ + __coverity_panic__(); +} + +template +class PoolAllocator +{ +public: + void* allocate(std::size_t size) + { + return __coverity_alloc__(size); + } + + void deallocate(const void* ptr) + { + __coverity_free__(ptr); + } +}; + +}