From c42a369d179db28baeca76e9037435adb40b6801 Mon Sep 17 00:00:00 2001 From: garethsb-sony Date: Tue, 21 Nov 2017 10:33:42 +0000 Subject: [PATCH 1/6] GCC 4.7 in experimental C++11 mode tokenises '<::' at the beginning of a template argument list or *_cast conversion incorrectly as the digraph '<:' (meaning '[') followed by a single ':'; the former can be resolved by -fpermissive, the latter isn't --- Release/CMakeLists.txt | 3 +++ Release/tests/functional/json/parsing_tests.cpp | 6 +++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/Release/CMakeLists.txt b/Release/CMakeLists.txt index 218adcbb34..4f02df386f 100644 --- a/Release/CMakeLists.txt +++ b/Release/CMakeLists.txt @@ -163,6 +163,9 @@ elseif(CMAKE_CXX_COMPILER_ID MATCHES "GNU") set(LD_FLAGS "${LD_FLAGS} -Wl,-z,defs") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -fno-strict-aliasing") + if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.8) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fpermissive") + endif() elseif(CMAKE_CXX_COMPILER_ID MATCHES "MSVC") message("-- Setting msvc options") diff --git a/Release/tests/functional/json/parsing_tests.cpp b/Release/tests/functional/json/parsing_tests.cpp index 2d4925d87a..c1cc7a8305 100644 --- a/Release/tests/functional/json/parsing_tests.cpp +++ b/Release/tests/functional/json/parsing_tests.cpp @@ -223,7 +223,7 @@ TEST(escaping_control_characters) for (int i : chars) { - ::utility::stringstream_t ss; + utility::stringstream_t ss; ss << U("\"\\u") << std::uppercase << std::setfill(U('0')) << std::setw(4) << std::hex << i << U("\""); const auto &str = ss.str(); auto expectedStr = str; @@ -257,8 +257,8 @@ TEST(escaping_control_characters) } // Try constructing a json string value directly. - ::utility::string_t schar; - schar.push_back(static_cast<::utility::string_t::value_type>(i)); + utility::string_t schar; + schar.push_back(static_cast(i)); const auto &sv = json::value::string(schar); VERIFY_ARE_EQUAL(expectedStr, sv.serialize()); From a282292b043e9eca64270b2e50c1071bcc83d2e3 Mon Sep 17 00:00:00 2001 From: garethsb-sony Date: Tue, 21 Nov 2017 10:39:16 +0000 Subject: [PATCH 2/6] Workaround for libstdc++ issue with GCC 4.7 (ultimately fixed in GCC 4.9) that means std::this_thread::yield() and std::this_thread::sleep_for() are only conditionally provided; see https://stackoverflow.com/a/12961816 --- Release/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Release/CMakeLists.txt b/Release/CMakeLists.txt index 4f02df386f..86a1a8475e 100644 --- a/Release/CMakeLists.txt +++ b/Release/CMakeLists.txt @@ -164,7 +164,7 @@ elseif(CMAKE_CXX_COMPILER_ID MATCHES "GNU") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -fno-strict-aliasing") if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.8) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fpermissive") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fpermissive -D_GLIBCXX_USE_SCHED_YIELD -D_GLIBCXX_USE_NANOSLEEP") endif() elseif(CMAKE_CXX_COMPILER_ID MATCHES "MSVC") From 7ee017664c8a8280ae7e835aa0ded9c47e858e19 Mon Sep 17 00:00:00 2001 From: garethsb-sony Date: Tue, 21 Nov 2017 10:41:12 +0000 Subject: [PATCH 3/6] At GCC 4.7, libstdc++ std::map didn't provide emplace(); using insert() is insignificant here --- Release/tests/common/TestRunner/test_runner.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Release/tests/common/TestRunner/test_runner.cpp b/Release/tests/common/TestRunner/test_runner.cpp index bb5160d4d9..7ec573dbbd 100644 --- a/Release/tests/common/TestRunner/test_runner.cpp +++ b/Release/tests/common/TestRunner/test_runner.cpp @@ -409,7 +409,7 @@ testlist_t load_all_tests(test_module_loader& module_loader) testlist_t testlists; // Retrieve the static tests and clear for dll loading. - testlists.emplace("", UnitTest::GetTestList()); + testlists.insert({ "", UnitTest::GetTestList() }); UnitTest::GetTestList().Clear(); // Cycle through all the test binaries and load them @@ -445,7 +445,7 @@ testlist_t load_all_tests(test_module_loader& module_loader) std::cout << "Loaded " << binary << "..." << std::endl; // Store the loaded binary into the test list map - testlists.emplace(binary, UnitTest::GetTestList()); + testlists.insert({ binary, UnitTest::GetTestList() }); UnitTest::GetTestList().Clear(); } } From 43a6f73cfe44b1954f5e5052e06ca96dba9f1707 Mon Sep 17 00:00:00 2001 From: garethsb-sony Date: Tue, 21 Nov 2017 10:45:51 +0000 Subject: [PATCH 4/6] At GCC 4.7, C++11 rules for noexcept specification of implicit destructors (and default specification on explicit destructors without exception specifications) aren't perfectly implemented --- Release/src/websockets/client/ws_client_wspp.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Release/src/websockets/client/ws_client_wspp.cpp b/Release/src/websockets/client/ws_client_wspp.cpp index e9e7658b18..dd1f809f6d 100644 --- a/Release/src/websockets/client/ws_client_wspp.cpp +++ b/Release/src/websockets/client/ws_client_wspp.cpp @@ -127,7 +127,7 @@ class wspp_callback_client : public websocket_client_callback_impl, public std:: #endif {} - ~wspp_callback_client() + ~wspp_callback_client() CPPREST_NOEXCEPT { _ASSERTE(m_state < DESTROYED); std::unique_lock lock(m_wspp_client_lock); @@ -730,6 +730,7 @@ class wspp_callback_client : public websocket_client_callback_impl, public std:: }; struct websocketpp_client : websocketpp_client_base { + ~websocketpp_client() CPPREST_NOEXCEPT {} websocketpp::client & non_tls_client() override { return m_client; @@ -739,6 +740,7 @@ class wspp_callback_client : public websocket_client_callback_impl, public std:: }; struct websocketpp_tls_client : websocketpp_client_base { + ~websocketpp_tls_client() CPPREST_NOEXCEPT {} websocketpp::client & tls_client() override { return m_client; From 5244af7ccf165709ec26c558dfcdb2531e0415cd Mon Sep 17 00:00:00 2001 From: garethsb-sony Date: Tue, 21 Nov 2017 12:42:42 +0000 Subject: [PATCH 5/6] =?UTF-8?q?At=20GCC=204.7,=20there=20are=20several=20b?= =?UTF-8?q?ugs=20that=20cause=20"error:=20=E2=80=98this=E2=80=99=20was=20n?= =?UTF-8?q?ot=20captured=20for=20this=20lambda=20function"=20to=20be=20rep?= =?UTF-8?q?orted=20incorrectly?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Release/src/http/client/http_client_asio.cpp | 28 +++++++++++++------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/Release/src/http/client/http_client_asio.cpp b/Release/src/http/client/http_client_asio.cpp index 19e09b2427..dc0e5daad3 100644 --- a/Release/src/http/client/http_client_asio.cpp +++ b/Release/src/http/client/http_client_asio.cpp @@ -44,6 +44,16 @@ #include #include +#if !defined(__GNUC__) || (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)) +#define AND_CAPTURE_MEMBER_FUNCTION_POINTERS +#else +// GCC Bug 56222 - Pointer to member in lambda should not require this to be captured +// See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56222 +// GCC Bug 51494 - Legal program rejection - capturing "this" when using static method inside lambda +// See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=51494 +#define AND_CAPTURE_MEMBER_FUNCTION_POINTERS , this +#endif + using boost::asio::ip::tcp; #ifdef __ANDROID__ @@ -620,7 +630,7 @@ class asio_context : public request_context, public std::enable_shared_from_this proxy_host = utility::conversions::to_utf8string(proxy_uri.host()); } - auto start_http_request_flow = [proxy_type, proxy_host, proxy_port](std::shared_ptr ctx) + auto start_http_request_flow = [proxy_type, proxy_host, proxy_port AND_CAPTURE_MEMBER_FUNCTION_POINTERS](std::shared_ptr ctx) { if (ctx->m_request._cancellation_token().is_canceled()) { @@ -1010,7 +1020,7 @@ class asio_context : public request_context, public std::enable_shared_from_this auto readbuf = _get_readbuffer(); uint8_t *buf = boost::asio::buffer_cast(m_body_buf.prepare(chunkSize + http::details::chunked_encoding::additional_encoding_space)); const auto this_request = shared_from_this(); - readbuf.getn(buf + http::details::chunked_encoding::data_offset, chunkSize).then([this_request, buf, chunkSize](pplx::task op) + readbuf.getn(buf + http::details::chunked_encoding::data_offset, chunkSize).then([this_request, buf, chunkSize AND_CAPTURE_MEMBER_FUNCTION_POINTERS](pplx::task op) { size_t readSize = 0; try @@ -1067,7 +1077,7 @@ class asio_context : public request_context, public std::enable_shared_from_this const auto this_request = shared_from_this(); const auto readSize = static_cast(std::min(static_cast(m_http_client->client_config().chunksize()), m_content_length - m_uploaded)); auto readbuf = _get_readbuffer(); - readbuf.getn(boost::asio::buffer_cast(m_body_buf.prepare(readSize)), readSize).then([this_request](pplx::task op) + readbuf.getn(boost::asio::buffer_cast(m_body_buf.prepare(readSize)), readSize).then([this_request AND_CAPTURE_MEMBER_FUNCTION_POINTERS](pplx::task op) { try { @@ -1370,7 +1380,7 @@ class asio_context : public request_context, public std::enable_shared_from_this auto shared_decompressed = std::make_shared(std::move(decompressed)); writeBuffer.putn_nocopy(shared_decompressed->data(), shared_decompressed->size()) - .then([this_request, to_read, shared_decompressed](pplx::task op) + .then([this_request, to_read, shared_decompressed AND_CAPTURE_MEMBER_FUNCTION_POINTERS](pplx::task op) { try { @@ -1388,7 +1398,7 @@ class asio_context : public request_context, public std::enable_shared_from_this } else { - writeBuffer.putn_nocopy(boost::asio::buffer_cast(m_body_buf.data()), to_read).then([this_request, to_read](pplx::task op) + writeBuffer.putn_nocopy(boost::asio::buffer_cast(m_body_buf.data()), to_read).then([this_request, to_read AND_CAPTURE_MEMBER_FUNCTION_POINTERS](pplx::task op) { try { @@ -1485,7 +1495,7 @@ class asio_context : public request_context, public std::enable_shared_from_this auto shared_decompressed = std::make_shared(std::move(decompressed)); writeBuffer.putn_nocopy(shared_decompressed->data(), shared_decompressed->size()) - .then([this_request, read_size, shared_decompressed](pplx::task op) + .then([this_request, read_size, shared_decompressed AND_CAPTURE_MEMBER_FUNCTION_POINTERS](pplx::task op) { size_t writtenSize = 0; try @@ -1507,7 +1517,7 @@ class asio_context : public request_context, public std::enable_shared_from_this else { writeBuffer.putn_nocopy(boost::asio::buffer_cast(m_body_buf.data()), read_size) - .then([this_request](pplx::task op) + .then([this_request AND_CAPTURE_MEMBER_FUNCTION_POINTERS](pplx::task op) { size_t writtenSize = 0; try @@ -1558,7 +1568,7 @@ class asio_context : public request_context, public std::enable_shared_from_this m_timer.expires_from_now(m_duration); auto ctx = m_ctx; - m_timer.async_wait([ctx](const boost::system::error_code& ec) + m_timer.async_wait([ctx AND_CAPTURE_MEMBER_FUNCTION_POINTERS](const boost::system::error_code& ec) { handle_timeout(ec, ctx); }); @@ -1573,7 +1583,7 @@ class asio_context : public request_context, public std::enable_shared_from_this // The existing handler was canceled so schedule a new one. assert(m_state == started); auto ctx = m_ctx; - m_timer.async_wait([ctx](const boost::system::error_code& ec) + m_timer.async_wait([ctx AND_CAPTURE_MEMBER_FUNCTION_POINTERS](const boost::system::error_code& ec) { handle_timeout(ec, ctx); }); From d0ce63e06422bd5eaa85cffb3aa39629c67ce4d9 Mon Sep 17 00:00:00 2001 From: garethsb-sony Date: Thu, 23 Nov 2017 17:03:51 +0000 Subject: [PATCH 6/6] VS2013 incorrectly reports "warning C4573: the usage of 'symbol' requires the compiler to capture 'this' but the current default capture mode does not allow it"; the issue and workaround is the same as for GCC 4.7 in commit:5244af7c. --- Release/src/http/client/http_client_asio.cpp | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/Release/src/http/client/http_client_asio.cpp b/Release/src/http/client/http_client_asio.cpp index dc0e5daad3..36e3b10362 100644 --- a/Release/src/http/client/http_client_asio.cpp +++ b/Release/src/http/client/http_client_asio.cpp @@ -44,7 +44,9 @@ #include #include -#if !defined(__GNUC__) || (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)) +#if defined(__GNUC__) + +#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) #define AND_CAPTURE_MEMBER_FUNCTION_POINTERS #else // GCC Bug 56222 - Pointer to member in lambda should not require this to be captured @@ -54,6 +56,21 @@ #define AND_CAPTURE_MEMBER_FUNCTION_POINTERS , this #endif +#elif defined(_MSC_VER) + +#if _MSC_VER >= 1900 +#define AND_CAPTURE_MEMBER_FUNCTION_POINTERS +#else +// This bug also afflicts VS2013 which incorrectly reports "warning C4573: the usage of 'symbol' requires the compiler to capture 'this' but the current default capture mode does not allow it" +#define AND_CAPTURE_MEMBER_FUNCTION_POINTERS , this +#endif + +#else + +#define AND_CAPTURE_MEMBER_FUNCTION_POINTERS + +#endif + using boost::asio::ip::tcp; #ifdef __ANDROID__