Commit d4493165 authored by Vladimir Glavnyy's avatar Vladimir Glavnyy Committed by Wouter van Oortmerssen

Fix high certainty warnings from PVS-studio (#5115)

* Fix high certainty warnings from PVS-studio

- Introduced FLATBUFFERS_ATTRIBUTE macro to use [[attribute]] if modern C++ compiler used

* Update the note about __cplusplus usage in the MSVC
parent bbfd12eb
...@@ -59,6 +59,15 @@ ...@@ -59,6 +59,15 @@
// Clang 3.4 and later implement all of the ISO C++ 2014 standard. // Clang 3.4 and later implement all of the ISO C++ 2014 standard.
// http://clang.llvm.org/cxx_status.html // http://clang.llvm.org/cxx_status.html
// Note the MSVC value '__cplusplus' may be incorrect:
// The '__cplusplus' predefined macro in the MSVC stuck at the value 199711L,
// indicating (erroneously!) that the compiler conformed to the C++98 Standard.
// This value should be correct starting from MSVC2017-15.7-Preview-3.
// The '__cplusplus' will be valid only if MSVC2017-15.7-P3 and the `/Zc:__cplusplus` switch is set.
// Workaround (for details see MSDN):
// Use the _MSC_VER and _MSVC_LANG definition instead of the __cplusplus for compatibility.
// The _MSVC_LANG macro reports the Standard version regardless of the '/Zc:__cplusplus' switch.
/// @cond FLATBUFFERS_INTERNAL /// @cond FLATBUFFERS_INTERNAL
#if __cplusplus <= 199711L && \ #if __cplusplus <= 199711L && \
(!defined(_MSC_VER) || _MSC_VER < 1600) && \ (!defined(_MSC_VER) || _MSC_VER < 1600) && \
...@@ -224,6 +233,15 @@ template<typename T> FLATBUFFERS_CONSTEXPR inline bool IsConstTrue(T t) { ...@@ -224,6 +233,15 @@ template<typename T> FLATBUFFERS_CONSTEXPR inline bool IsConstTrue(T t) {
return !!t; return !!t;
} }
// Enable of std:c++17 or higher.
#if (defined(__cplusplus) && (__cplusplus >= 201703L)) || \
(defined(_MSVC_LANG) && (_MSVC_LANG >= 201703L))
// All attributes unknown to an implementation are ignored without causing an error.
#define FLATBUFFERS_ATTRIBUTE(attr) // [[attr]] - will be enabled in a future release
#else
#define FLATBUFFERS_ATTRIBUTE(attr)
#endif
/// @endcond /// @endcond
/// @file /// @file
......
...@@ -211,6 +211,7 @@ template<typename T> class Vector { ...@@ -211,6 +211,7 @@ template<typename T> class Vector {
uoffset_t size() const { return EndianScalar(length_); } uoffset_t size() const { return EndianScalar(length_); }
// Deprecated: use size(). Here for backwards compatibility. // Deprecated: use size(). Here for backwards compatibility.
FLATBUFFERS_ATTRIBUTE(deprecated("use size() instead"))
uoffset_t Length() const { return size(); } uoffset_t Length() const { return size(); }
typedef typename IndirectHelper<T>::return_type return_type; typedef typename IndirectHelper<T>::return_type return_type;
...@@ -996,8 +997,8 @@ class FlatBufferBuilder { ...@@ -996,8 +997,8 @@ class FlatBufferBuilder {
/// @warning Do NOT attempt to use this FlatBufferBuilder afterwards! /// @warning Do NOT attempt to use this FlatBufferBuilder afterwards!
/// @return A `FlatBuffer` that owns the buffer and its allocator and /// @return A `FlatBuffer` that owns the buffer and its allocator and
/// behaves similar to a `unique_ptr` with a deleter. /// behaves similar to a `unique_ptr` with a deleter.
/// Deprecated: use Release() instead FLATBUFFERS_ATTRIBUTE(deprecated("use Release() instead")) DetachedBuffer
DetachedBuffer ReleaseBufferPointer() { ReleaseBufferPointer() {
Finished(); Finished();
return buf_.release(); return buf_.release();
} }
...@@ -1205,7 +1206,7 @@ class FlatBufferBuilder { ...@@ -1205,7 +1206,7 @@ class FlatBufferBuilder {
auto vt_offset_ptr = reinterpret_cast<uoffset_t *>(it); auto vt_offset_ptr = reinterpret_cast<uoffset_t *>(it);
auto vt2 = reinterpret_cast<voffset_t *>(buf_.data_at(*vt_offset_ptr)); auto vt2 = reinterpret_cast<voffset_t *>(buf_.data_at(*vt_offset_ptr));
auto vt2_size = *vt2; auto vt2_size = *vt2;
if (vt1_size != vt2_size || memcmp(vt2, vt1, vt1_size)) continue; if (vt1_size != vt2_size || 0 != memcmp(vt2, vt1, vt1_size)) continue;
vt_use = *vt_offset_ptr; vt_use = *vt_offset_ptr;
buf_.pop(GetSize() - vtableoffsetloc); buf_.pop(GetSize() - vtableoffsetloc);
break; break;
...@@ -1226,7 +1227,7 @@ class FlatBufferBuilder { ...@@ -1226,7 +1227,7 @@ class FlatBufferBuilder {
return vtableoffsetloc; return vtableoffsetloc;
} }
// DEPRECATED: call the version above instead. FLATBUFFERS_ATTRIBUTE(deprecated("call the version above instead"))
uoffset_t EndTable(uoffset_t start, voffset_t /*numfields*/) { uoffset_t EndTable(uoffset_t start, voffset_t /*numfields*/) {
return EndTable(start); return EndTable(start);
} }
...@@ -2114,7 +2115,7 @@ class Verifier FLATBUFFERS_FINAL_CLASS { ...@@ -2114,7 +2115,7 @@ class Verifier FLATBUFFERS_FINAL_CLASS {
if (!Verify<uoffset_t>(start)) return 0; if (!Verify<uoffset_t>(start)) return 0;
auto o = ReadScalar<uoffset_t>(buf_ + start); auto o = ReadScalar<uoffset_t>(buf_ + start);
// May not point to itself. // May not point to itself.
Check(o != 0); if (!Check(o != 0)) return 0;
// Can't wrap around / buffers are max 2GB. // Can't wrap around / buffers are max 2GB.
if (!Check(static_cast<soffset_t>(o) >= 0)) return 0; if (!Check(static_cast<soffset_t>(o) >= 0)) return 0;
// Must be inside the buffer to create a pointer from it (pointer outside // Must be inside the buffer to create a pointer from it (pointer outside
......
...@@ -326,7 +326,7 @@ inline size_t InlineAlignment(const Type &type) { ...@@ -326,7 +326,7 @@ inline size_t InlineAlignment(const Type &type) {
struct EnumVal { struct EnumVal {
EnumVal(const std::string &_name, int64_t _val) : name(_name), value(_val) {} EnumVal(const std::string &_name, int64_t _val) : name(_name), value(_val) {}
EnumVal(){}; EnumVal() : value(0){};
Offset<reflection::EnumVal> Serialize(FlatBufferBuilder *builder, const Parser &parser) const; Offset<reflection::EnumVal> Serialize(FlatBufferBuilder *builder, const Parser &parser) const;
...@@ -672,7 +672,7 @@ class Parser : public ParserState { ...@@ -672,7 +672,7 @@ class Parser : public ParserState {
bool Deserialize(const reflection::Schema* schema); bool Deserialize(const reflection::Schema* schema);
Type* DeserializeType(const reflection::Type* type); Type* DeserializeType(const reflection::Type* type);
// Checks that the schema represented by this parser is a safe evolution // Checks that the schema represented by this parser is a safe evolution
// of the schema provided. Returns non-empty error on any problems. // of the schema provided. Returns non-empty error on any problems.
std::string ConformTo(const Parser &base); std::string ConformTo(const Parser &base);
......
...@@ -72,7 +72,7 @@ class Registry { ...@@ -72,7 +72,7 @@ class Registry {
return DetachedBuffer(); return DetachedBuffer();
} }
// We have a valid FlatBuffer. Detach it from the builder and return. // We have a valid FlatBuffer. Detach it from the builder and return.
return parser.builder_.ReleaseBufferPointer(); return parser.builder_.Release();
} }
// Modify any parsing / output options used by the other functions. // Modify any parsing / output options used by the other functions.
......
...@@ -66,7 +66,7 @@ inline bool is_digit(char c) { return check_in_range(c, '0', '9'); } ...@@ -66,7 +66,7 @@ inline bool is_digit(char c) { return check_in_range(c, '0', '9'); }
inline bool is_xdigit(char c) { inline bool is_xdigit(char c) {
// Replace by look-up table. // Replace by look-up table.
return is_digit(c) | check_in_range(c & 0xDF, 'a' & 0xDF, 'f' & 0xDF); return is_digit(c) || check_in_range(c & 0xDF, 'a' & 0xDF, 'f' & 0xDF);
} }
// Case-insensitive isalnum // Case-insensitive isalnum
......
...@@ -44,7 +44,7 @@ int main(int /*argc*/, const char * /*argv*/[]) { ...@@ -44,7 +44,7 @@ int main(int /*argc*/, const char * /*argv*/[]) {
flatbuffers::Parser parser1; flatbuffers::Parser parser1;
ok = parser1.Parse(schema_file.c_str(), include_directories); ok = parser1.Parse(schema_file.c_str(), include_directories);
assert(ok); assert(ok);
// inizialize parser by deserializing bfbs schema // inizialize parser by deserializing bfbs schema
flatbuffers::Parser parser2; flatbuffers::Parser parser2;
ok = parser2.Deserialize((uint8_t *)bfbs_file.c_str(), bfbs_file.length()); ok = parser2.Deserialize((uint8_t *)bfbs_file.c_str(), bfbs_file.length());
...@@ -52,6 +52,7 @@ int main(int /*argc*/, const char * /*argv*/[]) { ...@@ -52,6 +52,7 @@ int main(int /*argc*/, const char * /*argv*/[]) {
// parse json in parser from fbs and bfbs // parse json in parser from fbs and bfbs
ok = parser1.Parse(json_file.c_str(), include_directories); ok = parser1.Parse(json_file.c_str(), include_directories);
assert(ok);
ok = parser2.Parse(json_file.c_str(), include_directories); ok = parser2.Parse(json_file.c_str(), include_directories);
assert(ok); assert(ok);
......
...@@ -411,8 +411,10 @@ CheckedError Parser::Next() { ...@@ -411,8 +411,10 @@ CheckedError Parser::Next() {
} }
cursor_ += 2; cursor_ += 2;
break; break;
} else {
// fall thru
} }
// fall thru FLATBUFFERS_ATTRIBUTE(fallthrough);
default: default:
const auto has_sign = (c == '+') || (c == '-'); const auto has_sign = (c == '+') || (c == '-');
// '-'/'+' and following identifier - can be a predefined constant like: // '-'/'+' and following identifier - can be a predefined constant like:
...@@ -2752,7 +2754,7 @@ bool StructDef::Deserialize(Parser &parser, const reflection::Object *object) { ...@@ -2752,7 +2754,7 @@ bool StructDef::Deserialize(Parser &parser, const reflection::Object *object) {
minalign = object->minalign(); minalign = object->minalign();
predecl = false; predecl = false;
sortbysize = attributes.Lookup("original_order") == nullptr && !fixed; sortbysize = attributes.Lookup("original_order") == nullptr && !fixed;
std::vector<uoffset_t> indexes = std::vector<uoffset_t> indexes =
std::vector<uoffset_t>(object->fields()->Length()); std::vector<uoffset_t>(object->fields()->Length());
for (uoffset_t i = 0; i < object->fields()->Length(); i++) for (uoffset_t i = 0; i < object->fields()->Length(); i++)
indexes[object->fields()->Get(i)->id()] = i; indexes[object->fields()->Get(i)->id()] = i;
...@@ -2768,7 +2770,7 @@ bool StructDef::Deserialize(Parser &parser, const reflection::Object *object) { ...@@ -2768,7 +2770,7 @@ bool StructDef::Deserialize(Parser &parser, const reflection::Object *object) {
// Recompute padding since that's currently not serialized. // Recompute padding since that's currently not serialized.
auto size = InlineSize(field_def->value.type); auto size = InlineSize(field_def->value.type);
auto next_field = auto next_field =
i + 1 < indexes.size() i + 1 < indexes.size()
? object->fields()->Get(indexes[i+1]) ? object->fields()->Get(indexes[i+1])
: nullptr; : nullptr;
bytesize += size; bytesize += size;
...@@ -3036,7 +3038,7 @@ bool Parser::Deserialize(const uint8_t *buf, const size_t size) { ...@@ -3036,7 +3038,7 @@ bool Parser::Deserialize(const uint8_t *buf, const size_t size) {
return false; return false;
else else
size_prefixed = true; size_prefixed = true;
} }
auto verify_fn = size_prefixed ? &reflection::VerifySizePrefixedSchemaBuffer auto verify_fn = size_prefixed ? &reflection::VerifySizePrefixedSchemaBuffer
: &reflection::VerifySchemaBuffer; : &reflection::VerifySchemaBuffer;
if (!verify_fn(verifier)) { if (!verify_fn(verifier)) {
......
...@@ -200,7 +200,7 @@ flatbuffers::DetachedBuffer CreateFlatBufferTest(std::string &buffer) { ...@@ -200,7 +200,7 @@ flatbuffers::DetachedBuffer CreateFlatBufferTest(std::string &buffer) {
reinterpret_cast<const char *>(builder.GetBufferPointer()); reinterpret_cast<const char *>(builder.GetBufferPointer());
buffer.assign(bufferpointer, bufferpointer + builder.GetSize()); buffer.assign(bufferpointer, bufferpointer + builder.GetSize());
return builder.ReleaseBufferPointer(); return builder.Release();
} }
// example of accessing a buffer loaded in memory: // example of accessing a buffer loaded in memory:
...@@ -2032,6 +2032,7 @@ void UnionVectorTest() { ...@@ -2032,6 +2032,7 @@ void UnionVectorTest() {
TEST_EQ(cts->GetEnum<Character>(4) == Character_Unused, true); TEST_EQ(cts->GetEnum<Character>(4) == Character_Unused, true);
auto rapunzel = movie->main_character_as_Rapunzel(); auto rapunzel = movie->main_character_as_Rapunzel();
TEST_NOTNULL(rapunzel);
TEST_EQ(rapunzel->hair_length(), 6); TEST_EQ(rapunzel->hair_length(), 6);
auto cs = movie->characters(); auto cs = movie->characters();
...@@ -2309,16 +2310,17 @@ void TypeAliasesTest() { ...@@ -2309,16 +2310,17 @@ void TypeAliasesTest() {
TEST_EQ(ta->u64(), flatbuffers::numeric_limits<uint64_t>::max()); TEST_EQ(ta->u64(), flatbuffers::numeric_limits<uint64_t>::max());
TEST_EQ(ta->f32(), 2.3f); TEST_EQ(ta->f32(), 2.3f);
TEST_EQ(ta->f64(), 2.3); TEST_EQ(ta->f64(), 2.3);
TEST_EQ(sizeof(ta->i8()), 1); using namespace flatbuffers; // is_same
TEST_EQ(sizeof(ta->i16()), 2); static_assert(is_same<decltype(ta->i8()), int8_t>::value, "invalid type");
TEST_EQ(sizeof(ta->i32()), 4); static_assert(is_same<decltype(ta->i16()), int16_t>::value, "invalid type");
TEST_EQ(sizeof(ta->i64()), 8); static_assert(is_same<decltype(ta->i32()), int32_t>::value, "invalid type");
TEST_EQ(sizeof(ta->u8()), 1); static_assert(is_same<decltype(ta->i64()), int64_t>::value, "invalid type");
TEST_EQ(sizeof(ta->u16()), 2); static_assert(is_same<decltype(ta->u8()), uint8_t>::value, "invalid type");
TEST_EQ(sizeof(ta->u32()), 4); static_assert(is_same<decltype(ta->u16()), uint16_t>::value, "invalid type");
TEST_EQ(sizeof(ta->u64()), 8); static_assert(is_same<decltype(ta->u32()), uint32_t>::value, "invalid type");
TEST_EQ(sizeof(ta->f32()), 4); static_assert(is_same<decltype(ta->u64()), uint64_t>::value, "invalid type");
TEST_EQ(sizeof(ta->f64()), 8); static_assert(is_same<decltype(ta->f32()), float>::value, "invalid type");
static_assert(is_same<decltype(ta->f64()), double>::value, "invalid type");
} }
void EndianSwapTest() { void EndianSwapTest() {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment