From a6eb15d274fbf0f8f6e0049c244f48fc476ddb5a Mon Sep 17 00:00:00 2001 From: Milo Yip Date: Sat, 23 Jan 2016 14:37:15 +0800 Subject: [PATCH 1/5] Fix warnings in clang for C++11 --- CMakeLists.txt | 8 +++++ example/serialize/serialize.cpp | 3 ++ include/rapidjson/document.h | 4 +-- include/rapidjson/internal/stack.h | 9 ++++++ include/rapidjson/internal/swap.h | 9 ++++++ include/rapidjson/stringbuffer.h | 9 ++++++ test/unittest/documenttest.cpp | 10 +++++++ test/unittest/readertest.cpp | 1 + test/unittest/stringbuffertest.cpp | 9 ++++++ test/unittest/unittest.cpp | 11 +++++++ test/unittest/unittest.h | 12 ++++++++ test/unittest/valuetest.cpp | 47 ++++++++++++++++++++++++------ 12 files changed, 121 insertions(+), 11 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 51ee620..5971bb7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,6 +20,8 @@ option(RAPIDJSON_BUILD_TESTS "Build rapidjson perftests and unittests." ON) option(RAPIDJSON_BUILD_THIRDPARTY_GTEST "Use gtest installation in `thirdparty/gtest` by default if available" OFF) +option(RAPIDJSON_BUILD_CXX11 "Build rapidjson with C++11 (gcc/clang)" ON) + option(RAPIDJSON_HAS_STDSTRING "" OFF) if(RAPIDJSON_HAS_STDSTRING) add_definitions(-DRAPIDJSON_HAS_STDSTRING) @@ -27,8 +29,14 @@ endif() if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=native -Wall -Wextra -Werror") + if (RAPIDJSON_BUILD_CXX11) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") + endif() elseif (CMAKE_CXX_COMPILER_ID MATCHES "Clang") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=native -Wall -Wextra -Werror -Wno-missing-field-initializers") + if (RAPIDJSON_BUILD_CXX11) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") + endif() elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") add_definitions(-D_CRT_SECURE_NO_WARNINGS=1) endif() diff --git a/example/serialize/serialize.cpp b/example/serialize/serialize.cpp index 6c5e5c2..cef5c66 100644 --- a/example/serialize/serialize.cpp +++ b/example/serialize/serialize.cpp @@ -11,6 +11,7 @@ using namespace rapidjson; class Person { public: Person(const std::string& name, unsigned age) : name_(name), age_(age) {} + Person(const Person& rhs) : name_(rhs.name_), age_(rhs.age_) {} virtual ~Person(); protected: @@ -38,6 +39,7 @@ Person::~Person() { class Education { public: Education(const std::string& school, double GPA) : school_(school), GPA_(GPA) {} + Education(const Education& rhs) : school_(rhs.school_), GPA_(rhs.GPA_) {} template void Serialize(Writer& writer) const { @@ -102,6 +104,7 @@ Dependent::~Dependent() { class Employee : public Person { public: Employee(const std::string& name, unsigned age, bool married) : Person(name, age), dependents_(), married_(married) {} + Employee(const Employee& rhs) : Person(rhs), dependents_(rhs.dependents_), married_(rhs.married_) {} virtual ~Employee(); void AddDependent(const Dependent& dependent) { diff --git a/include/rapidjson/document.h b/include/rapidjson/document.h index 095aa40..12187ea 100644 --- a/include/rapidjson/document.h +++ b/include/rapidjson/document.h @@ -31,6 +31,7 @@ RAPIDJSON_DIAG_OFF(4127) // conditional expression is constant RAPIDJSON_DIAG_PUSH RAPIDJSON_DIAG_OFF(padded) RAPIDJSON_DIAG_OFF(switch-enum) +RAPIDJSON_DIAG_OFF(c++98-compat) #endif #ifdef __GNUC__ @@ -141,6 +142,7 @@ public: Otherwise, the copy constructor is implicitly defined. */ GenericMemberIterator(const NonConstIterator & it) : ptr_(it.ptr_) {} + Iterator& operator=(const NonConstIterator & it) { ptr_ = it.ptr_; return *this; } //! @name stepping //@{ @@ -314,8 +316,6 @@ struct GenericStringRef { const SizeType length; //!< length of the string (excluding the trailing NULL terminator) private: - //! Disallow copy-assignment - GenericStringRef operator=(const GenericStringRef&); //! Disallow construction from non-const array template GenericStringRef(CharType (&str)[N]) /* = delete */; diff --git a/include/rapidjson/internal/stack.h b/include/rapidjson/internal/stack.h index 3d691d3..12f8a8f 100644 --- a/include/rapidjson/internal/stack.h +++ b/include/rapidjson/internal/stack.h @@ -18,6 +18,11 @@ #include "../rapidjson.h" #include "swap.h" +#if defined(__clang__) +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(c++98-compat) +#endif + RAPIDJSON_NAMESPACE_BEGIN namespace internal { @@ -203,4 +208,8 @@ private: } // namespace internal RAPIDJSON_NAMESPACE_END +#if defined(__clang__) +RAPIDJSON_DIAG_POP +#endif + #endif // RAPIDJSON_STACK_H_ diff --git a/include/rapidjson/internal/swap.h b/include/rapidjson/internal/swap.h index 39bc2e4..cbb2abd 100644 --- a/include/rapidjson/internal/swap.h +++ b/include/rapidjson/internal/swap.h @@ -17,6 +17,11 @@ #include "../rapidjson.h" +#if defined(__clang__) +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(c++98-compat) +#endif + RAPIDJSON_NAMESPACE_BEGIN namespace internal { @@ -34,4 +39,8 @@ inline void Swap(T& a, T& b) RAPIDJSON_NOEXCEPT { } // namespace internal RAPIDJSON_NAMESPACE_END +#if defined(__clang__) +RAPIDJSON_DIAG_POP +#endif + #endif // RAPIDJSON_INTERNAL_SWAP_H_ diff --git a/include/rapidjson/stringbuffer.h b/include/rapidjson/stringbuffer.h index 40b51cd..0d32859 100644 --- a/include/rapidjson/stringbuffer.h +++ b/include/rapidjson/stringbuffer.h @@ -23,6 +23,11 @@ #include "internal/stack.h" +#if defined(__clang__) +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(c++98-compat) +#endif + RAPIDJSON_NAMESPACE_BEGIN //! Represents an in-memory output stream. @@ -103,4 +108,8 @@ inline void PutN(GenericStringBuffer >& stream, char c, size_t n) { RAPIDJSON_NAMESPACE_END +#if defined(__clang__) +RAPIDJSON_DIAG_POP +#endif + #endif // RAPIDJSON_STRINGBUFFER_H_ diff --git a/test/unittest/documenttest.cpp b/test/unittest/documenttest.cpp index cdc4c31..c3438f3 100644 --- a/test/unittest/documenttest.cpp +++ b/test/unittest/documenttest.cpp @@ -21,6 +21,12 @@ #include #include +#ifdef __clang__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(c++98-compat) +RAPIDJSON_DIAG_OFF(missing-variable-declarations) +#endif + using namespace rapidjson; template @@ -573,3 +579,7 @@ TYPED_TEST(DocumentMove, MoveAssignmentStack) { // Document d2; // d1 = d2; //} + +#ifdef __clang__ +RAPIDJSON_DIAG_POP +#endif diff --git a/test/unittest/readertest.cpp b/test/unittest/readertest.cpp index 3b84ab7..49888a9 100644 --- a/test/unittest/readertest.cpp +++ b/test/unittest/readertest.cpp @@ -31,6 +31,7 @@ RAPIDJSON_DIAG_OFF(missing-noreturn) #ifdef __clang__ RAPIDJSON_DIAG_PUSH RAPIDJSON_DIAG_OFF(variadic-macros) +RAPIDJSON_DIAG_OFF(c++98-compat-pedantic) #endif template diff --git a/test/unittest/stringbuffertest.cpp b/test/unittest/stringbuffertest.cpp index fbacf51..28fdbc5 100644 --- a/test/unittest/stringbuffertest.cpp +++ b/test/unittest/stringbuffertest.cpp @@ -16,6 +16,11 @@ #include "rapidjson/stringbuffer.h" #include "rapidjson/writer.h" +#ifdef __clang__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(c++98-compat) +#endif + using namespace rapidjson; TEST(StringBuffer, InitialSize) { @@ -148,3 +153,7 @@ TEST(StringBuffer, MoveAssignment) { } #endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS + +#ifdef __clang__ +RAPIDJSON_DIAG_POP +#endif diff --git a/test/unittest/unittest.cpp b/test/unittest/unittest.cpp index dd562a2..655518a 100644 --- a/test/unittest/unittest.cpp +++ b/test/unittest/unittest.cpp @@ -15,8 +15,19 @@ #include "unittest.h" #include "rapidjson/rapidjson.h" +#ifdef __clang__ +#pragma GCC diagnostic push +#if __has_warning("-Wdeprecated") +#pragma GCC diagnostic ignored "-Wdeprecated" +#endif +#endif + AssertException::~AssertException() throw() {} +#ifdef __clang__ +#pragma GCC diagnostic pop +#endif + int main(int argc, char **argv) { ::testing::InitGoogleTest(&argc, argv); diff --git a/test/unittest/unittest.h b/test/unittest/unittest.h index 6062410..60e6c18 100644 --- a/test/unittest/unittest.h +++ b/test/unittest/unittest.h @@ -99,12 +99,24 @@ inline FILE* TempFile(char *filename) { #pragma warning(disable : 4127) #endif +#ifdef __clang__ +#pragma GCC diagnostic push +#if __has_warning("-Wdeprecated") +#pragma GCC diagnostic ignored "-Wdeprecated" +#endif +#endif + class AssertException : public std::logic_error { public: AssertException(const char* w) : std::logic_error(w) {} + AssertException(const AssertException& rhs) : std::logic_error(rhs) {} virtual ~AssertException() throw(); }; +#ifdef __clang__ +#pragma GCC diagnostic pop +#endif + #define RAPIDJSON_ASSERT(x) if (!(x)) throw AssertException(RAPIDJSON_STRINGIFY(x)) class Random { diff --git a/test/unittest/valuetest.cpp b/test/unittest/valuetest.cpp index 245ccac..b2963fc 100644 --- a/test/unittest/valuetest.cpp +++ b/test/unittest/valuetest.cpp @@ -16,6 +16,11 @@ #include "rapidjson/document.h" #include +#ifdef __clang__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(c++98-compat) +#endif + using namespace rapidjson; TEST(Value, DefaultConstructor) { @@ -764,15 +769,15 @@ TEST(Value, Array) { #if RAPIDJSON_HAS_CXX11_RVALUE_REFS // PushBack(GenericValue&&, Allocator&); { - Value y(kArrayType); - y.PushBack(Value(true), allocator); - y.PushBack(std::move(Value(kArrayType).PushBack(Value(1), allocator).PushBack("foo", allocator)), allocator); - EXPECT_EQ(2u, y.Size()); - EXPECT_TRUE(y[0].IsTrue()); - EXPECT_TRUE(y[1].IsArray()); - EXPECT_EQ(2u, y[1].Size()); - EXPECT_TRUE(y[1][0].IsInt()); - EXPECT_TRUE(y[1][1].IsString()); + Value y2(kArrayType); + y2.PushBack(Value(true), allocator); + y2.PushBack(std::move(Value(kArrayType).PushBack(Value(1), allocator).PushBack("foo", allocator)), allocator); + EXPECT_EQ(2u, y2.Size()); + EXPECT_TRUE(y2[0].IsTrue()); + EXPECT_TRUE(y2[1].IsArray()); + EXPECT_EQ(2u, y2[1].Size()); + EXPECT_TRUE(y2[1][0].IsInt()); + EXPECT_TRUE(y2[1][1].IsString()); } #endif @@ -1354,3 +1359,27 @@ TEST(Value, AcceptTerminationByHandler) { TEST_TERMINATION(11, "{\"a\":[]}"); TEST_TERMINATION(12, "{\"a\":[]}"); } + +struct ValueIntComparer { + bool operator()(const Value& lhs, const Value& rhs) const { + return lhs.GetInt() < rhs.GetInt(); + } +}; + +#if RAPIDJSON_HAS_CXX11_RVALUE_REFS +TEST(Value, Sorting) { + Value::AllocatorType allocator; + Value a(kArrayType); + a.PushBack(5, allocator); + a.PushBack(1, allocator); + a.PushBack(3, allocator); + std::sort(a.Begin(), a.End(), ValueIntComparer()); + EXPECT_EQ(1, a[0].GetInt()); + EXPECT_EQ(3, a[1].GetInt()); + EXPECT_EQ(5, a[2].GetInt()); +} +#endif + +#ifdef __clang__ +RAPIDJSON_DIAG_POP +#endif From 2f5a69b2fb7ed305a0de0a8d7bacc63c1dfeb0b3 Mon Sep 17 00:00:00 2001 From: Milo Yip Date: Sat, 23 Jan 2016 14:58:19 +0800 Subject: [PATCH 2/5] Try using c++0x for gcc 4.6.x --- CMakeLists.txt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5971bb7..33f3ef9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -30,7 +30,11 @@ endif() if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=native -Wall -Wextra -Werror") if (RAPIDJSON_BUILD_CXX11) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") + if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS "4.7.0") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x") + else() + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") + endif() endif() elseif (CMAKE_CXX_COMPILER_ID MATCHES "Clang") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=native -Wall -Wextra -Werror -Wno-missing-field-initializers") From d8c793f23f1b092638f464528789a6c1f4b57c44 Mon Sep 17 00:00:00 2001 From: Milo Yip Date: Sat, 23 Jan 2016 15:27:59 +0800 Subject: [PATCH 3/5] Disable type_traits --- test/unittest/documenttest.cpp | 4 ++++ test/unittest/stringbuffertest.cpp | 4 ++++ test/unittest/valuetest.cpp | 4 ++++ 3 files changed, 12 insertions(+) diff --git a/test/unittest/documenttest.cpp b/test/unittest/documenttest.cpp index c3438f3..1b1c469 100644 --- a/test/unittest/documenttest.cpp +++ b/test/unittest/documenttest.cpp @@ -334,6 +334,8 @@ TEST(Document, UTF16_Document) { #if RAPIDJSON_HAS_CXX11_RVALUE_REFS +#if 0 // Many old compiler does not support these. Turn it off temporaily. + #include TEST(Document, Traits) { @@ -371,6 +373,8 @@ TEST(Document, Traits) { #endif } +#endif + template struct DocumentMove: public ::testing::Test { }; diff --git a/test/unittest/stringbuffertest.cpp b/test/unittest/stringbuffertest.cpp index 28fdbc5..9be98fc 100644 --- a/test/unittest/stringbuffertest.cpp +++ b/test/unittest/stringbuffertest.cpp @@ -74,6 +74,8 @@ TEST(StringBuffer, Pop) { #if RAPIDJSON_HAS_CXX11_RVALUE_REFS +#if 0 // Many old compiler does not support these. Turn it off temporaily. + #include TEST(StringBuffer, Traits) { @@ -111,6 +113,8 @@ TEST(StringBuffer, Traits) { #endif } +#endif + TEST(StringBuffer, MoveConstructor) { StringBuffer x; x.Put('A'); diff --git a/test/unittest/valuetest.cpp b/test/unittest/valuetest.cpp index b2963fc..5cecdc7 100644 --- a/test/unittest/valuetest.cpp +++ b/test/unittest/valuetest.cpp @@ -39,6 +39,8 @@ TEST(Value, DefaultConstructor) { #if RAPIDJSON_HAS_CXX11_RVALUE_REFS +#if 0 // Many old compiler does not support these. Turn it off temporaily. + #include TEST(Value, Traits) { @@ -77,6 +79,8 @@ TEST(Value, Traits) { #endif } +#endif + TEST(Value, MoveConstructor) { typedef GenericValue, CrtAllocator> Value; Value::AllocatorType allocator; From a7490404ba1e323673297765484b8ec7e7431bec Mon Sep 17 00:00:00 2001 From: Milo Yip Date: Sat, 23 Jan 2016 15:38:01 +0800 Subject: [PATCH 4/5] Try to fix a clang missing assignment warning --- example/serialize/serialize.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/example/serialize/serialize.cpp b/example/serialize/serialize.cpp index cef5c66..a7f330e 100644 --- a/example/serialize/serialize.cpp +++ b/example/serialize/serialize.cpp @@ -14,6 +14,12 @@ public: Person(const Person& rhs) : name_(rhs.name_), age_(rhs.age_) {} virtual ~Person(); + Person& operator=(const Person& rhs) { + name_ = rhs.name_; + age_ = rhs.age_; + return *this; + } + protected: template void Serialize(Writer& writer) const { @@ -107,6 +113,13 @@ public: Employee(const Employee& rhs) : Person(rhs), dependents_(rhs.dependents_), married_(rhs.married_) {} virtual ~Employee(); + Employee& operator=(const Employee& rhs) { + static_cast(*this) = rhs; + dependents_ = rhs.dependents_; + married_ = rhs.married_; + return *this; + } + void AddDependent(const Dependent& dependent) { dependents_.push_back(dependent); } From 403115019b26b92e146dd0174438e8c79c688cdd Mon Sep 17 00:00:00 2001 From: Milo Yip Date: Sat, 23 Jan 2016 15:53:27 +0800 Subject: [PATCH 5/5] Add travis C++11 on/off matrix --- .travis.yml | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index be06f35..78fe1d5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,10 +6,12 @@ compiler: env: matrix: - - CONF=debug ARCH=x86_64 - - CONF=release ARCH=x86_64 - - CONF=debug ARCH=x86 - - CONF=release ARCH=x86 + - CONF=debug ARCH=x86_64 CXX11=ON + - CONF=release ARCH=x86_64 CXX11=ON + - CONF=debug ARCH=x86 CXX11=ON + - CONF=release ARCH=x86 CXX11=ON + - CONF=debug ARCH=x86_64 CXX11=OFF + - CONF=debug ARCH=x86 CXX11=OFF global: - ARCH_FLAGS_x86='-m32' # #266: don't use SSE on 32-bit - ARCH_FLAGS_x86_64='-msse4.2' # use SSE4.2 on 64-bit @@ -34,6 +36,7 @@ before_script: eval "ARCH_FLAGS=\${ARCH_FLAGS_${ARCH}}" ; (cd build && cmake -DRAPIDJSON_HAS_STDSTRING=ON + -DRAPIDJSON_BUILD_CXX11=$CXX11 -DCMAKE_VERBOSE_MAKEFILE=ON -DCMAKE_BUILD_TYPE=$CONF -DCMAKE_CXX_FLAGS="$ARCH_FLAGS $GCOV_FLAGS"