diff --git a/Makefile.in b/Makefile.in index 84d4320e..ded867ce 100644 --- a/Makefile.in +++ b/Makefile.in @@ -65,7 +65,7 @@ tests/results:$(TEST_RESULT) @echo -------------- Test Results --------------- @cat tests/results @echo ------------------------------------------- - @ ! grep -qv OK tests/results + @ ! grep -qv 'OK\|Skipped' tests/results #Build a test executable from a test program. On compile error, @@ -87,6 +87,9 @@ tests/%.result_: tests/%.test if [ $$a -ge 128 and ] ; \ then \ echo Crash!! > $@ ; \ + elif [ $$a -eq 42 ] ;\ + then \ + echo Skipped > $@ ; \ elif [ $$a -ne 126 ] ;\ then \ echo Failed > $@ ; \ diff --git a/hdr/sqlite_modern_cpp.h b/hdr/sqlite_modern_cpp.h index df729faf..0e68deff 100644 --- a/hdr/sqlite_modern_cpp.h +++ b/hdr/sqlite_modern_cpp.h @@ -24,7 +24,8 @@ #include -#include +#include "sqlite_modern_cpp/utility/function_traits.h" +#include "sqlite_modern_cpp/utility/uncaught_exceptions.h" namespace sqlite { @@ -160,6 +161,7 @@ namespace sqlite { private: std::shared_ptr _db; std::unique_ptr _stmt; + utility::UncaughtExceptionDetector _has_uncaught_exception; int _inx; @@ -285,7 +287,7 @@ namespace sqlite { ~database_binder() noexcept(false) { /* Will be executed if no >>op is found, but not if an exception is in mid flight */ - if(!execution_started && !std::uncaught_exception() && _stmt) { + if(!execution_started && !_has_uncaught_exception && _stmt) { execute(); } } diff --git a/hdr/sqlite_modern_cpp/utility/uncaught_exceptions.h b/hdr/sqlite_modern_cpp/utility/uncaught_exceptions.h new file mode 100644 index 00000000..17d63263 --- /dev/null +++ b/hdr/sqlite_modern_cpp/utility/uncaught_exceptions.h @@ -0,0 +1,27 @@ +#pragma once + +#include +#include +#include + +namespace sqlite { + namespace utility { +#ifdef __cpp_lib_uncaught_exceptions + class UncaughtExceptionDetector { + public: + operator bool() { + return count != std::uncaught_exceptions(); + } + private: + int count = std::uncaught_exceptions(); + }; +#else + class UncaughtExceptionDetector { + public: + operator bool() { + return std::uncaught_exception(); + } + }; +#endif + } +} diff --git a/tests/exception_dont_execute.cc b/tests/exception_dont_execute.cc new file mode 100644 index 00000000..ac708fe9 --- /dev/null +++ b/tests/exception_dont_execute.cc @@ -0,0 +1,20 @@ +#include +#include +#include +#include +#include +using namespace sqlite; +using namespace std; + + +int main() { + database db(":memory:"); + db << "CREATE TABLE person (id integer primary key not null, name TEXT not null);"; + + try { + auto stmt = db << "INSERT INTO person (id,name) VALUES (?,?)"; + throw 1; + } catch (int) { + } + exit(EXIT_SUCCESS); +} diff --git a/tests/exception_dont_execute_nested.cc b/tests/exception_dont_execute_nested.cc new file mode 100644 index 00000000..5d814356 --- /dev/null +++ b/tests/exception_dont_execute_nested.cc @@ -0,0 +1,32 @@ +#include +#include +#include +#include +#include +using namespace sqlite; +using namespace std; + +struct A { + ~A() { + database db(":memory:"); + db << "CREATE TABLE person (id integer primary key not null, name TEXT not null);"; + + try { + auto stmt = db << "INSERT INTO person (id,name) VALUES (?,?)"; + throw 1; + } catch (int) { + } + } +}; +int main() { +#ifdef __cpp_lib_uncaught_exceptions + try { + A a; + throw 1; + } catch(int) { + } + exit(EXIT_SUCCESS); +#else + exit(42); +#endif +} diff --git a/tests/std_optional.cc b/tests/std_optional.cc index cb748ccf..5d182626 100644 --- a/tests/std_optional.cc +++ b/tests/std_optional.cc @@ -70,6 +70,6 @@ int main() { #else #pragma message " not found, test disabled." int main() { - exit(EXIT_SUCCESS); + exit(42); } #endif