From d0d5f29def1e252f39c9ce6de1c807aa06fc7dea Mon Sep 17 00:00:00 2001 From: Carlos Rafael Giani Date: Thu, 9 Jul 2020 09:13:20 +0200 Subject: [PATCH 1/4] Fix compiler version detection and print compiler information The existing script fails to detect compiler versions properly if the major version has more than one digit. For example, with clang version 10, the script incorrectly interprets the version number as "1". Fix the script to parse the digits until the first dot as the major version instead, thus preserving the correct major version number. (head -n1 is added in case the version number is mentioned more than once by ${CXX} --version.) Also, print the version number and the compiler when building to make sure the correct compiler and version number were detected. --- Makefile | 2 ++ misc/compiler-major-version.sh | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index db16ecd..2e0cb9f 100644 --- a/Makefile +++ b/Makefile @@ -4,6 +4,8 @@ BUILD := build/$(VARIANT) COMPILER := $(shell CXX="${CXX}" misc/compiler.sh) COMPILER_MAJOR_VERSION := $(shell CXX="${CXX}" misc/compiler-major-version.sh) +$(info Compiler: "${COMPILER}" major version: "${COMPILER_MAJOR_VERSION}") + ifeq ($(COMPILER), clang) CXXFLAGS_WARNINGS := -Weverything -Wno-c++98-compat -Wno-c++98-compat-pedantic -Wno-exit-time-destructors ifeq ($(shell test $(COMPILER_MAJOR_VERSION) -gt 4; echo $$?),0) diff --git a/misc/compiler-major-version.sh b/misc/compiler-major-version.sh index 42e4cc4..6bde360 100755 --- a/misc/compiler-major-version.sh +++ b/misc/compiler-major-version.sh @@ -6,8 +6,8 @@ compiler=$(${CXX} -v 2>&1) case $compiler in *clang*|*gcc*) - version=`${CXX} --version | grep -o '\([0-9]\)\+.\([0-9]\)\+.\([0-9]\)\+'` - echo ${version::1} + version=`${CXX} --version | grep -o '\([0-9]\)\+.\([0-9]\)\+.\([0-9]\)\+' | sed -e 's/^\([0-9]*\).*/\1/' | head -n1` + echo "${version}" ;; *) echo From 17fbef205fcf7ed6800e6d7d49f4508ab18a7001 Mon Sep 17 00:00:00 2001 From: Carlos Rafael Giani Date: Thu, 9 Jul 2020 09:14:24 +0200 Subject: [PATCH 2/4] Fix shadowed arguments "ptr" may already exist in the base class. A simple fix is to rename the ptr instances in unique.hpp to "ptr_". Otherwise, clang reports errors. --- include/jni/unique.hpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/include/jni/unique.hpp b/include/jni/unique.hpp index 2abf490..c17e992 100644 --- a/include/jni/unique.hpp +++ b/include/jni/unique.hpp @@ -47,12 +47,12 @@ namespace jni using Base = T; using UntaggedType = typename T::UntaggedType; - explicit Unique(std::nullptr_t ptr = nullptr) - : T(ptr), + explicit Unique(std::nullptr_t ptr_ = nullptr) + : T(ptr_), deleter() {} - explicit Unique(JNIEnv& env, UntaggedType* ptr) - : T(ptr), + explicit Unique(JNIEnv& env, UntaggedType* ptr_) + : T(ptr_), deleter(env) {} Unique(Unique&& other) @@ -76,10 +76,10 @@ namespace jni return *this; } - void reset(UntaggedType* ptr = nullptr) + void reset(UntaggedType* ptr_ = nullptr) { UntaggedType* current = this->get(); - T::reset(ptr); + T::reset(ptr_); if (current) { get_deleter()(current); From 4ab1bae57bcce1b4ad80b4bad2f1cb08705a7207 Mon Sep 17 00:00:00 2001 From: Carlos Rafael Giani Date: Thu, 9 Jul 2020 09:16:47 +0200 Subject: [PATCH 3/4] Workaround for GCC specific signed - unsigned comparison MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When building with GCC 9, this comparison causes this error: comparison of integer expressions of different signedness: ‘jni::jsize’ {aka ‘long unsigned int’} and ‘int’ As a workaround, explicitely cast the return value of max() to jsize (not ::jsize !). --- include/jni/wrapping.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/jni/wrapping.hpp b/include/jni/wrapping.hpp index be2989f..010243d 100644 --- a/include/jni/wrapping.hpp +++ b/include/jni/wrapping.hpp @@ -72,7 +72,7 @@ namespace jni ::jsize Unwrap(jsize s) const { - if (s > std::numeric_limits<::jsize>::max()) + if (s > jsize(std::numeric_limits<::jsize>::max())) throw std::range_error("jsize > max"); return static_cast<::jsize>(s); } From 572226ef82dec4bd1ad5b3f938e0f0ca8004a2de Mon Sep 17 00:00:00 2001 From: Carlos Rafael Giani Date: Thu, 9 Jul 2020 09:21:17 +0200 Subject: [PATCH 4/4] Fix GCC compile error due to incompatible type cast MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GCC 9 complains about these reinterpret_cast expressions because of the different return value: error: cast between incompatible function types from ‘void (*)(JNIEnv*, jni::jobject*, jni::jobject*)’ {aka ‘void (*)(_JNIEnv*, jni::jobject*, jni::jobject*)’} to ‘jboolean (*)(JNIEnv*, jobject, jobject)’ {aka ‘unsigned char (*)(_JNIEnv*, _jobject*, _jobject*)’} Fix by using void as return value. --- test/high_level.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/high_level.cpp b/test/high_level.cpp index 73ca270..91b06fe 100644 --- a/test/high_level.cpp +++ b/test/high_level.cpp @@ -669,15 +669,15 @@ int main() auto voidTrue = jni::MakeNativeMethod("voidTrue", [] (JNIEnv&, ObjectOrClass&, jni::jboolean b) { assert( b); }); assert(voidTrue.signature == std::string("(Z)V")); - reinterpret_cast(voidTrue.fnPtr)(&env, nullptr, JNI_TRUE); + reinterpret_cast(voidTrue.fnPtr)(&env, nullptr, JNI_TRUE); auto voidFalse = jni::MakeNativeMethod("voidFalse", [] (JNIEnv&, ObjectOrClass&, jni::jboolean b) { assert(!b); }); assert(voidFalse.signature == std::string("(Z)V")); - reinterpret_cast(voidFalse.fnPtr)(&env, nullptr, JNI_FALSE); + reinterpret_cast(voidFalse.fnPtr)(&env, nullptr, JNI_FALSE); auto voidObject = jni::MakeNativeMethod("voidObject", [] (JNIEnv&, ObjectOrClass&, jni::Object&) {}); assert(voidObject.signature == std::string("(Lmapbox/com/Test;)V")); - reinterpret_cast(voidObject.fnPtr)(&env, nullptr, nullptr); + reinterpret_cast(voidObject.fnPtr)(&env, nullptr, nullptr); auto objectVoid = jni::MakeNativeMethod("objectVoid", [] (JNIEnv&, ObjectOrClass&) -> jni::Local> { return jni::Local>(); }); assert(objectVoid.signature == std::string("()Lmapbox/com/Test;"));