summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Szewczyk <git@kubasz.xyz>2022-03-18 22:10:04 +0000
committerGitHub <noreply@github.com>2022-03-18 15:10:04 -0700
commit88c2e4377df7dbe65bc8ef629ea409cd9df6a860 (patch)
tree0fe699c08ef55ed5902304e55851cdb1796c6881
parent967245fbc75217d257eeba15ede4aeb56e3c0d89 (diff)
downloadbinaryen-88c2e4377df7dbe65bc8ef629ea409cd9df6a860.tar.gz
binaryen-88c2e4377df7dbe65bc8ef629ea409cd9df6a860.tar.bz2
binaryen-88c2e4377df7dbe65bc8ef629ea409cd9df6a860.zip
Fix errors when building in C++20 mode (#4528)
* use [[noreturn]] available since C++11 instead of compiler-specific attributes * replace deprecated std::is_pod with is_trivial&&is_standard_layout (also available since C++11/14) * explicitly capture this in [=] lambdas * extra const functions in FeatureSet, fix implicit cast warning by using the features field directly * Use CMAKE_CXX_STANDARD to ensure the C++ standard parameter is set on all targets, remove manual compiler flag workaround.
-rw-r--r--CMakeLists.txt20
-rw-r--r--src/compiler-support.h8
-rw-r--r--src/support/utilities.cpp5
-rw-r--r--src/support/utilities.h15
-rw-r--r--src/tools/tool-options.h4
-rw-r--r--src/wasm-features.h6
6 files changed, 26 insertions, 32 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 97a90f8f5..7eae4d3c6 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -12,7 +12,15 @@ include(GNUInstallDirs)
# The C++ standard whose features are required to build Binaryen.
# Keep in sync with scripts/test/shared.py cxx_standard
-set(CXX_STANDARD 17)
+# The if condition allows embedding in a project with a higher default C++ standard set
+set(REQUIRED_CXX_STANDARD 17)
+if(NOT CMAKE_CXX_STANDARD)
+ set(CMAKE_CXX_STANDARD ${REQUIRED_CXX_STANDARD})
+elseif(CMAKE_CXX_STANDARD LESS ${REQUIRED_CXX_STANDARD})
+ message(SEND_ERROR "Building with C++ standards older than C++${REQUIRED_CXX_STANDARD} is not supported, change CMAKE_CXX_STANDARD to ${REQUIRED_CXX_STANDARD} or later")
+endif()
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
+set(CMAKE_CXX_EXTENSIONS OFF)
if(NOT CMAKE_BUILD_TYPE)
message(STATUS "No build type selected, default to Release")
@@ -109,8 +117,6 @@ function(binaryen_add_executable name sources)
add_executable(${name} ${sources})
target_link_libraries(${name} ${CMAKE_THREAD_LIBS_INIT})
target_link_libraries(${name} binaryen)
- set_property(TARGET ${name} PROPERTY CXX_STANDARD ${CXX_STANDARD})
- set_property(TARGET ${name} PROPERTY CXX_STANDARD_REQUIRED ON)
binaryen_setup_rpath(${name})
install(TARGETS ${name} DESTINATION ${CMAKE_INSTALL_BINDIR})
endfunction()
@@ -175,12 +181,11 @@ if(MSVC)
add_compile_flag("/arch:sse2")
endif()
endif()
- add_compile_flag("/std:c++${CXX_STANDARD}")
add_compile_flag("/wd4146") # Ignore warning "warning C4146: unary minus operator applied to unsigned type, result still unsigned", this pattern is used somewhat commonly in the code.
# 4267 and 4244 are conversion/truncation warnings. We might want to fix these but they are currently pervasive.
add_compile_flag("/wd4267")
add_compile_flag("/wd4244")
- # 4722 warns that destructors never return, even with WASM_NORETURN.
+ # 4722 warns that destructors never return, even with [[noreturn]].
add_compile_flag("/wd4722")
# "destructor was implicitly defined as deleted" caused by LLVM headers.
add_compile_flag("/wd4624")
@@ -233,7 +238,6 @@ else()
set(THREADS_PREFER_PTHREAD_FLAG ON)
set(CMAKE_THREAD_PREFER_PTHREAD ON)
find_package(Threads REQUIRED)
- add_cxx_flag("-std=c++${CXX_STANDARD}")
if(NOT EMSCRIPTEN)
if(CMAKE_SYSTEM_PROCESSOR MATCHES "^i.86$")
# wasm doesn't allow for x87 floating point math
@@ -384,8 +388,6 @@ if(EMSCRIPTEN)
target_link_libraries(binaryen_wasm optimized "--closure-args \"--language_in=ECMASCRIPT6 --language_out=ECMASCRIPT6\"")
target_link_libraries(binaryen_wasm optimized "-flto")
target_link_libraries(binaryen_wasm debug "--profiling")
- set_property(TARGET binaryen_wasm PROPERTY CXX_STANDARD ${CXX_STANDARD})
- set_property(TARGET binaryen_wasm PROPERTY CXX_STANDARD_REQUIRED ON)
install(TARGETS binaryen_wasm DESTINATION ${CMAKE_INSTALL_BINDIR})
# binaryen.js JavaScript variant
@@ -409,8 +411,6 @@ if(EMSCRIPTEN)
target_link_libraries(binaryen_js optimized "-flto")
target_link_libraries(binaryen_js debug "--profiling")
target_link_libraries(binaryen_js debug "-s ASSERTIONS")
- set_property(TARGET binaryen_js PROPERTY CXX_STANDARD ${CXX_STANDARD})
- set_property(TARGET binaryen_js PROPERTY CXX_STANDARD_REQUIRED ON)
install(TARGETS binaryen_js DESTINATION ${CMAKE_INSTALL_BINDIR})
endif()
diff --git a/src/compiler-support.h b/src/compiler-support.h
index 5f3edacea..eddb2d7f0 100644
--- a/src/compiler-support.h
+++ b/src/compiler-support.h
@@ -31,14 +31,6 @@
#define WASM_BUILTIN_UNREACHABLE __assume(false)
#endif
-#ifdef __GNUC__
-#define WASM_NORETURN __attribute__((noreturn))
-#elif defined(_MSC_VER)
-#define WASM_NORETURN __declspec(noreturn)
-#else
-#define WASM_NORETURN
-#endif
-
// The code might contain TODOs or stubs that read some values but do nothing
// with them. The compiler might fail with [-Werror,-Wunused-variable].
// The WASM_UNUSED(varible) is a wrapper that helps to suppress the error.
diff --git a/src/support/utilities.cpp b/src/support/utilities.cpp
index ea426df9c..f051a1871 100644
--- a/src/support/utilities.cpp
+++ b/src/support/utilities.cpp
@@ -24,9 +24,8 @@
#include "sanitizer/common_interface_defs.h"
#endif
-void wasm::handle_unreachable(const char* msg,
- const char* file,
- unsigned line) {
+[[noreturn]] void
+wasm::handle_unreachable(const char* msg, const char* file, unsigned line) {
#ifndef NDEBUG
if (msg) {
std::cerr << msg << "\n";
diff --git a/src/support/utilities.h b/src/support/utilities.h
index 38fe6fd73..57d170269 100644
--- a/src/support/utilities.h
+++ b/src/support/utilities.h
@@ -36,8 +36,11 @@ template<class Destination, class Source>
inline Destination bit_cast(const Source& source) {
static_assert(sizeof(Destination) == sizeof(Source),
"bit_cast needs to be between types of the same size");
- static_assert(std::is_pod<Destination>::value, "non-POD bit_cast undefined");
- static_assert(std::is_pod<Source>::value, "non-POD bit_cast undefined");
+ static_assert(std::is_trivial_v<Destination> &&
+ std::is_standard_layout_v<Destination>,
+ "non-POD bit_cast undefined");
+ static_assert(std::is_trivial_v<Source> && std::is_standard_layout_v<Source>,
+ "non-POD bit_cast undefined");
Destination destination;
std::memcpy(&destination, &source, sizeof(destination));
return destination;
@@ -65,7 +68,7 @@ public:
std::cerr << arg;
return *this;
}
- WASM_NORETURN ~Fatal() {
+ [[noreturn]] ~Fatal() {
std::cerr << "\n";
// Use _Exit here to avoid calling static destructors. This avoids deadlocks
// in (for example) the thread worker pool, where workers hold a lock while
@@ -74,9 +77,9 @@ public:
}
};
-WASM_NORETURN void handle_unreachable(const char* msg = nullptr,
- const char* file = nullptr,
- unsigned line = 0);
+[[noreturn]] void handle_unreachable(const char* msg = nullptr,
+ const char* file = nullptr,
+ unsigned line = 0);
// If control flow reaches the point of the WASM_UNREACHABLE(), the program is
// undefined.
diff --git a/src/tools/tool-options.h b/src/tools/tool-options.h
index 0ed0f27fb..f8278e950 100644
--- a/src/tools/tool-options.h
+++ b/src/tools/tool-options.h
@@ -155,7 +155,7 @@ struct ToolOptions : public Options {
std::string("Enable ") + description,
ToolOptionsCategory,
Arguments::Zero,
- [=](Options*, const std::string&) {
+ [this, feature](Options*, const std::string&) {
enabledFeatures.set(feature, true);
disabledFeatures.set(feature, false);
})
@@ -165,7 +165,7 @@ struct ToolOptions : public Options {
std::string("Disable ") + description,
ToolOptionsCategory,
Arguments::Zero,
- [=](Options*, const std::string&) {
+ [this, feature](Options*, const std::string&) {
enabledFeatures.set(feature, false);
disabledFeatures.set(feature, true);
});
diff --git a/src/wasm-features.h b/src/wasm-features.h
index 7311aadd3..02e1660bb 100644
--- a/src/wasm-features.h
+++ b/src/wasm-features.h
@@ -82,7 +82,7 @@ struct FeatureSet {
}
}
- std::string toString() {
+ std::string toString() const {
std::string ret;
uint32_t x = 1;
while (x & Feature::All) {
@@ -102,7 +102,7 @@ struct FeatureSet {
operator uint32_t() const { return features; }
bool isMVP() const { return features == MVP; }
- bool has(FeatureSet f) { return (features & f) == f; }
+ bool has(FeatureSet f) const { return (features & f) == f.features; }
bool hasAtomics() const { return (features & Atomics) != 0; }
bool hasMutableGlobals() const { return (features & MutableGlobals) != 0; }
bool hasTruncSat() const { return (features & TruncSat) != 0; }
@@ -165,7 +165,7 @@ struct FeatureSet {
features = features & ~other.features & All;
}
- template<typename F> void iterFeatures(F f) {
+ template<typename F> void iterFeatures(F f) const {
for (uint32_t feature = MVP + 1; feature < All; feature <<= 1) {
if (has(feature)) {
f(static_cast<Feature>(feature));