diff --git a/include/flatbuffers/base.h b/include/flatbuffers/base.h index 26adcc961..36820554c 100644 --- a/include/flatbuffers/base.h +++ b/include/flatbuffers/base.h @@ -59,6 +59,15 @@ // Clang 3.4 and later implement all of the ISO C++ 2014 standard. // 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 #if __cplusplus <= 199711L && \ (!defined(_MSC_VER) || _MSC_VER < 1600) && \ @@ -224,6 +233,15 @@ template FLATBUFFERS_CONSTEXPR inline bool IsConstTrue(T 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 /// @file diff --git a/include/flatbuffers/flatbuffers.h b/include/flatbuffers/flatbuffers.h index cb796b0dd..3f7cbbebe 100644 --- a/include/flatbuffers/flatbuffers.h +++ b/include/flatbuffers/flatbuffers.h @@ -211,6 +211,7 @@ template class Vector { uoffset_t size() const { return EndianScalar(length_); } // Deprecated: use size(). Here for backwards compatibility. + FLATBUFFERS_ATTRIBUTE(deprecated("use size() instead")) uoffset_t Length() const { return size(); } typedef typename IndirectHelper::return_type return_type; @@ -996,8 +997,8 @@ class FlatBufferBuilder { /// @warning Do NOT attempt to use this FlatBufferBuilder afterwards! /// @return A `FlatBuffer` that owns the buffer and its allocator and /// behaves similar to a `unique_ptr` with a deleter. - /// Deprecated: use Release() instead - DetachedBuffer ReleaseBufferPointer() { + FLATBUFFERS_ATTRIBUTE(deprecated("use Release() instead")) DetachedBuffer + ReleaseBufferPointer() { Finished(); return buf_.release(); } @@ -1205,7 +1206,7 @@ class FlatBufferBuilder { auto vt_offset_ptr = reinterpret_cast(it); auto vt2 = reinterpret_cast(buf_.data_at(*vt_offset_ptr)); 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; buf_.pop(GetSize() - vtableoffsetloc); break; @@ -1226,7 +1227,7 @@ class FlatBufferBuilder { 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*/) { return EndTable(start); } @@ -2114,7 +2115,7 @@ class Verifier FLATBUFFERS_FINAL_CLASS { if (!Verify(start)) return 0; auto o = ReadScalar(buf_ + start); // May not point to itself. - Check(o != 0); + if (!Check(o != 0)) return 0; // Can't wrap around / buffers are max 2GB. if (!Check(static_cast(o) >= 0)) return 0; // Must be inside the buffer to create a pointer from it (pointer outside diff --git a/include/flatbuffers/idl.h b/include/flatbuffers/idl.h index 00e6af5e6..e48edb01e 100644 --- a/include/flatbuffers/idl.h +++ b/include/flatbuffers/idl.h @@ -326,7 +326,7 @@ inline size_t InlineAlignment(const Type &type) { struct EnumVal { EnumVal(const std::string &_name, int64_t _val) : name(_name), value(_val) {} - EnumVal(){}; + EnumVal() : value(0){}; Offset Serialize(FlatBufferBuilder *builder, const Parser &parser) const; @@ -672,7 +672,7 @@ class Parser : public ParserState { bool Deserialize(const reflection::Schema* schema); Type* DeserializeType(const reflection::Type* type); - + // Checks that the schema represented by this parser is a safe evolution // of the schema provided. Returns non-empty error on any problems. std::string ConformTo(const Parser &base); diff --git a/include/flatbuffers/registry.h b/include/flatbuffers/registry.h index f90fc8d29..9ea425b39 100644 --- a/include/flatbuffers/registry.h +++ b/include/flatbuffers/registry.h @@ -72,7 +72,7 @@ class Registry { return DetachedBuffer(); } // 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. diff --git a/include/flatbuffers/util.h b/include/flatbuffers/util.h index 7509676c4..3bd8e978c 100644 --- a/include/flatbuffers/util.h +++ b/include/flatbuffers/util.h @@ -66,7 +66,7 @@ inline bool is_digit(char c) { return check_in_range(c, '0', '9'); } inline bool is_xdigit(char c) { // 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 diff --git a/samples/sample_bfbs.cpp b/samples/sample_bfbs.cpp index e2424de4f..9512e242c 100644 --- a/samples/sample_bfbs.cpp +++ b/samples/sample_bfbs.cpp @@ -44,7 +44,7 @@ int main(int /*argc*/, const char * /*argv*/[]) { flatbuffers::Parser parser1; ok = parser1.Parse(schema_file.c_str(), include_directories); assert(ok); - + // inizialize parser by deserializing bfbs schema flatbuffers::Parser parser2; ok = parser2.Deserialize((uint8_t *)bfbs_file.c_str(), bfbs_file.length()); @@ -52,6 +52,7 @@ int main(int /*argc*/, const char * /*argv*/[]) { // parse json in parser from fbs and bfbs ok = parser1.Parse(json_file.c_str(), include_directories); + assert(ok); ok = parser2.Parse(json_file.c_str(), include_directories); assert(ok); diff --git a/src/idl_parser.cpp b/src/idl_parser.cpp index 9e607ca60..698c9ab08 100644 --- a/src/idl_parser.cpp +++ b/src/idl_parser.cpp @@ -411,8 +411,10 @@ CheckedError Parser::Next() { } cursor_ += 2; break; + } else { + // fall thru } - // fall thru + FLATBUFFERS_ATTRIBUTE(fallthrough); default: const auto has_sign = (c == '+') || (c == '-'); // '-'/'+' and following identifier - can be a predefined constant like: @@ -2752,7 +2754,7 @@ bool StructDef::Deserialize(Parser &parser, const reflection::Object *object) { minalign = object->minalign(); predecl = false; sortbysize = attributes.Lookup("original_order") == nullptr && !fixed; - std::vector indexes = + std::vector indexes = std::vector(object->fields()->Length()); for (uoffset_t i = 0; i < object->fields()->Length(); i++) indexes[object->fields()->Get(i)->id()] = i; @@ -2768,7 +2770,7 @@ bool StructDef::Deserialize(Parser &parser, const reflection::Object *object) { // Recompute padding since that's currently not serialized. auto size = InlineSize(field_def->value.type); auto next_field = - i + 1 < indexes.size() + i + 1 < indexes.size() ? object->fields()->Get(indexes[i+1]) : nullptr; bytesize += size; @@ -3036,7 +3038,7 @@ bool Parser::Deserialize(const uint8_t *buf, const size_t size) { return false; else size_prefixed = true; - } + } auto verify_fn = size_prefixed ? &reflection::VerifySizePrefixedSchemaBuffer : &reflection::VerifySchemaBuffer; if (!verify_fn(verifier)) { diff --git a/tests/test.cpp b/tests/test.cpp index 76d3efe3c..744846674 100644 --- a/tests/test.cpp +++ b/tests/test.cpp @@ -200,7 +200,7 @@ flatbuffers::DetachedBuffer CreateFlatBufferTest(std::string &buffer) { reinterpret_cast(builder.GetBufferPointer()); buffer.assign(bufferpointer, bufferpointer + builder.GetSize()); - return builder.ReleaseBufferPointer(); + return builder.Release(); } // example of accessing a buffer loaded in memory: @@ -2032,6 +2032,7 @@ void UnionVectorTest() { TEST_EQ(cts->GetEnum(4) == Character_Unused, true); auto rapunzel = movie->main_character_as_Rapunzel(); + TEST_NOTNULL(rapunzel); TEST_EQ(rapunzel->hair_length(), 6); auto cs = movie->characters(); @@ -2309,16 +2310,17 @@ void TypeAliasesTest() { TEST_EQ(ta->u64(), flatbuffers::numeric_limits::max()); TEST_EQ(ta->f32(), 2.3f); TEST_EQ(ta->f64(), 2.3); - TEST_EQ(sizeof(ta->i8()), 1); - TEST_EQ(sizeof(ta->i16()), 2); - TEST_EQ(sizeof(ta->i32()), 4); - TEST_EQ(sizeof(ta->i64()), 8); - TEST_EQ(sizeof(ta->u8()), 1); - TEST_EQ(sizeof(ta->u16()), 2); - TEST_EQ(sizeof(ta->u32()), 4); - TEST_EQ(sizeof(ta->u64()), 8); - TEST_EQ(sizeof(ta->f32()), 4); - TEST_EQ(sizeof(ta->f64()), 8); + using namespace flatbuffers; // is_same + static_assert(is_samei8()), int8_t>::value, "invalid type"); + static_assert(is_samei16()), int16_t>::value, "invalid type"); + static_assert(is_samei32()), int32_t>::value, "invalid type"); + static_assert(is_samei64()), int64_t>::value, "invalid type"); + static_assert(is_sameu8()), uint8_t>::value, "invalid type"); + static_assert(is_sameu16()), uint16_t>::value, "invalid type"); + static_assert(is_sameu32()), uint32_t>::value, "invalid type"); + static_assert(is_sameu64()), uint64_t>::value, "invalid type"); + static_assert(is_samef32()), float>::value, "invalid type"); + static_assert(is_samef64()), double>::value, "invalid type"); } void EndianSwapTest() {