From 11c794e0799ecfadaf35f6d603ec451c449624bb Mon Sep 17 00:00:00 2001 From: Daniel Arndt Date: Thu, 6 Sep 2018 21:54:09 +0200 Subject: [PATCH] Check for the ability to call non-constepr functions in constexpr ones --- cmake/checks/check_01_cxx_features.cmake | 29 ++++++++++++++++++++++++ include/deal.II/base/config.h.in | 1 + include/deal.II/base/utilities.h | 6 +++-- 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/cmake/checks/check_01_cxx_features.cmake b/cmake/checks/check_01_cxx_features.cmake index 9b44082564..a9a6ce7ea0 100644 --- a/cmake/checks/check_01_cxx_features.cmake +++ b/cmake/checks/check_01_cxx_features.cmake @@ -23,6 +23,7 @@ # # DEAL_II_HAVE_ATTRIBUTE_FALLTHROUGH # DEAL_II_HAVE_CXX11_IS_TRIVIALLY_COPYABLE +# DEAL_II_HAVE_CXX14_CONSTEXPR_CAN_CALL_NONCONSTEXPR # DEAL_II_HAVE_CXX17_SPECIAL_MATH_FUNCTIONS # DEAL_II_HAVE_FP_EXCEPTIONS # DEAL_II_HAVE_COMPLEX_OPERATOR_OVERLOADS @@ -552,6 +553,7 @@ UNSET_IF_CHANGED(CHECK_CXX_FEATURES_FLAGS_SAVED "${CMAKE_REQUIRED_FLAGS}${DEAL_II_CXX_VERSION_FLAG}${DEAL_II_WITH_CXX14}${DEAL_II_WITH_CXX17}" DEAL_II_HAVE_ATTRIBUTE_FALLTHROUGH DEAL_II_HAVE_CXX11_IS_TRIVIALLY_COPYABLE + DEAL_II_HAVE_CXX14_CONSTEXPR_CAN_CALL_NONCONSTEXPR DEAL_II_HAVE_CXX17_SPECIAL_MATH_FUNCTIONS DEAL_II_HAVE_FP_EXCEPTIONS DEAL_II_HAVE_COMPLEX_OPERATOR_OVERLOADS @@ -668,6 +670,33 @@ CHECK_CXX_SOURCE_COMPILES( " DEAL_II_HAVE_COMPLEX_OPERATOR_OVERLOADS) +# +# As long as there exists an argument value such that an invocation of the +# function or constructor could be an evaluated subexpression of a core constant +# expression, C++14 allows to call non-constexpr functions from constexpr +# functions. Unfortunately, not all compilers obey the standard in this regard. +# +CHECK_CXX_SOURCE_COMPILES( + " + void bar() + {} + + constexpr int + foo(const int n) + { + if(!(n >= 0)) + bar(); + return n; + } + + int main() + { + constexpr unsigned int n=foo(1); + return n; + } + " + DEAL_II_HAVE_CXX14_CONSTEXPR_CAN_CALL_NONCONSTEXPR) + # # Not all compilers with C++17 support include the new special math # functions. Check this separately so that we can use C++17 compilers that don't diff --git a/include/deal.II/base/config.h.in b/include/deal.II/base/config.h.in index af22c18563..c32f0dd5b7 100644 --- a/include/deal.II/base/config.h.in +++ b/include/deal.II/base/config.h.in @@ -122,6 +122,7 @@ */ #cmakedefine DEAL_II_HAVE_CXX11_IS_TRIVIALLY_COPYABLE +#cmakedefine DEAL_II_HAVE_CXX14_CONSTEXPR_CAN_CALL_NONCONSTEXPR #cmakedefine DEAL_II_HAVE_CXX17_SPECIAL_MATH_FUNCTIONS #cmakedefine DEAL_II_HAVE_FP_EXCEPTIONS #cmakedefine DEAL_II_HAVE_COMPLEX_OPERATOR_OVERLOADS diff --git a/include/deal.II/base/utilities.h b/include/deal.II/base/utilities.h index 491796bd18..44d83cd612 100644 --- a/include/deal.II/base/utilities.h +++ b/include/deal.II/base/utilities.h @@ -354,7 +354,8 @@ namespace Utilities pow(const unsigned int base, const int iexp) { #ifdef DEAL_II_WITH_CXX14 -# if defined(DEAL_II_HAVE_BUILTIN_EXPECT) && defined(__INTEL_COMPILER) +# ifdef DEAL_II_HAVE_CXX14_CONSTEXPR_CAN_CALL_NONCONSTEXPR +# if defined(DEAL_II_HAVE_BUILTIN_EXPECT) && defined(__INTEL_COMPILER) if (!(iexp >= 0)) ::dealii::deal_II_exceptions::internals::issue_error_noreturn( ::dealii::deal_II_exceptions::internals::abort_or_throw_on_exception, @@ -364,8 +365,9 @@ namespace Utilities "iexp>=0", "ExcMessage(\"The exponent must not be negative!\")", ExcMessage("The exponent must not be negative!")); -# else +# else Assert(iexp >= 0, ExcMessage("The exponent must not be negative!")); +# endif # endif #endif // The "exponentiation by squaring" algorithm used below has to be -- 2.39.5