From 6e799253f4aa4322fd85c48572ffb92371e17600 Mon Sep 17 00:00:00 2001 From: maier Date: Wed, 12 Sep 2012 14:00:19 +0000 Subject: [PATCH] Add some more tests for compiler features git-svn-id: https://svn.dealii.org/branches/branch_cmake@26312 0785d39b-7218-0410-832d-ea1e28bc413d --- deal.II/compiler-mumbo-jumbo.m4 | 221 ------------------ .../check/check_for_compiler_features.cmake | 139 +++++++++++ deal.II/include/deal.II/base/config.h.in | 14 ++ deal.II/include/deal.II/base/config.h.in.old | 15 -- 4 files changed, 153 insertions(+), 236 deletions(-) diff --git a/deal.II/compiler-mumbo-jumbo.m4 b/deal.II/compiler-mumbo-jumbo.m4 index 672322683c..0880785d94 100644 --- a/deal.II/compiler-mumbo-jumbo.m4 +++ b/deal.II/compiler-mumbo-jumbo.m4 @@ -2384,224 +2384,3 @@ AC_DEFUN(DEAL_II_CHECK_WSYNTH_AND_STD_COMPLEX, dnl ]) fi ]) - - - -dnl ------------------------------------------------------------- -dnl Check for existence of the __builtin_expect facility of newer -dnl gcc compilers. This can be used to hint the compiler's branch -dnl prediction unit in some cases. We use it in the AssertThrow -dnl macros. -dnl -dnl Annoyingly, the Portland Group compiler compiles code with -dnl __builtin_expect just fine, but then doesn't want to link it, -dnl saying it doesn't know this function. So simply not test for -dnl __builtin_expect with that compiler, and to be extrasure make -dnl sure we're doing the right thing also link . -dnl -dnl Usage: DEAL_II_HAVE_BUILTIN_EXPECT -dnl -dnl ------------------------------------------------------------- -AC_DEFUN(DEAL_II_HAVE_BUILTIN_EXPECT, dnl -[ - if test ! "x$GXX_BRAND" = "PortlandGroup" ; then - AC_MSG_CHECKING(for __builtin_expect) - AC_LANG(C++) - CXXFLAGS="$CXXFLAGSG" - AC_TRY_LINK( - [ - bool f() {} - ], - [ - if (__builtin_expect(f(),false)); - ], - [ - AC_MSG_RESULT(yes) - AC_DEFINE(HAVE_BUILTIN_EXPECT, 1, - [Define if the compiler provides __builtin_expect]) - ], - [ - AC_MSG_RESULT(no) - ]) - fi -]) - - - -dnl ------------------------------------------------------------- -dnl Newer versions of gcc have a very nice feature: you can set -dnl a verbose terminate handler, that not only aborts a program -dnl when an exception is thrown and not caught somewhere, but -dnl before aborting it prints that an exception has been thrown, -dnl and possibly what the std::exception::what() function has to -dnl say. Since many people run into the trap of not having a -dnl catch clause in main(), they wonder where that abort may be -dnl coming from. The terminate handler then at least says what is -dnl missing in their program. -dnl -dnl This test checks whether this feature is available. -dnl -dnl Usage: DEAL_II_HAVE_VERBOSE_TERMINATE -dnl -dnl ------------------------------------------------------------- -AC_DEFUN(DEAL_II_HAVE_VERBOSE_TERMINATE, dnl -[ - AC_MSG_CHECKING(for __verbose_terminate_handler) - AC_LANG(C++) - CXXFLAGS="$CXXFLAGSG" - AC_TRY_LINK( - [ -#include - -namespace __gnu_cxx -{ - extern void __verbose_terminate_handler (); -} - -struct preload_terminate_dummy -{ - preload_terminate_dummy() - { std::set_terminate (__gnu_cxx::__verbose_terminate_handler); } -}; - -static preload_terminate_dummy dummy; - ], - [ - throw 1; - ], - [ - AC_MSG_RESULT(yes) - AC_DEFINE(HAVE_VERBOSE_TERMINATE, 1, - [Define if the compiler provides __verbose_terminate_handler]) - ], - [ - AC_MSG_RESULT(no) - ]) -]) - -dnl ------------------------------------------------------------- -dnl Check whether glibc-like stacktrace information is available -dnl for the Exception class. If it is, then try to also determine -dnl whether the compiler accepts the -rdynamic flag, since that is -dnl recommended for linking if one wants to have meaningful -dnl backtraces. -dnl -dnl Usage: DEAL_II_HAVE_GLIBC_STACKTRACE -dnl -dnl ------------------------------------------------------------- -AC_DEFUN(DEAL_II_HAVE_GLIBC_STACKTRACE, dnl -[ - AC_MSG_CHECKING(for glibc-like stacktrace information) - AC_LANG(C++) - CXXFLAGS="$CXXFLAGSG" - AC_TRY_COMPILE( - [ -#include -#include - ], - [ - void * array[25]; - int nSize = backtrace(array, 25); - char ** symbols = backtrace_symbols(array, nSize); - free(symbols); - ], - [ - AC_MSG_RESULT(yes) - AC_DEFINE(HAVE_GLIBC_STACKTRACE, 1, - [Define if deal.II is linked against a libc that - provides stacktrace debug information that can be - printed out in the exception class]) - - dnl On Mac OS X, -rdynamic is accepted by the compiler (i.e. - dnl it doesn't produce an error) but we always get a warning - dnl that it isn't supported. That's pretty stupid because - dnl we can't test for it. Consequently, only run the test - dnl if not on OS X. - case "$target" in - *apple-darwin*) - ;; - - *) - AC_MSG_CHECKING(whether compiler accepts -rdynamic) - - CXXFLAGS="$CXXFLAGSG -rdynamic" - AC_TRY_LINK( - [], - [;], - [ - AC_MSG_RESULT(yes) - LDFLAGS="$LDFLAGS -rdynamic" - ], - [ - AC_MSG_RESULT(no) - ]) - ;; - esac - ], - [ - AC_MSG_RESULT(no) - ]) -]) - - - -dnl ------------------------------------------------------------- -dnl Check whether the compiler offers a way to demangle symbols -dnl from within the program. Used inside the exception stacktrace -dnl mechanism. -dnl -dnl The example code is taken from -dnl http://gcc.gnu.org/onlinedocs/libstdc++/18_support/howto.html#6 -dnl -dnl Usage: DEAL_II_HAVE_DEMANGLER -dnl -dnl ------------------------------------------------------------- -AC_DEFUN(DEAL_II_HAVE_DEMANGLER, dnl -[ - AC_MSG_CHECKING(for libstdc++ demangler) - AC_LANG(C++) - CXXFLAGS="$CXXFLAGSG" - AC_TRY_LINK( - [ -#include -#include -#include -#include - -struct empty { }; - -template - struct bar { }; - ], - [ - int status; - char *realname; - - // exception classes not in , thrown by the implementation - // instead of the user - std::bad_exception e; - realname = abi::__cxa_demangle(e.what(), 0, 0, &status); - std::cout << e.what() << "\t=> " << realname << "\t: " << status << '\n'; - free(realname); - - - // typeid - bar u; - const std::type_info &ti = typeid(u); - - realname = abi::__cxa_demangle(ti.name(), 0, 0, &status); - std::cout << ti.name() << "\t=> " << realname << "\t: " << status << '\n'; - free(realname); - - return 0; - ], - [ - AC_MSG_RESULT(yes) - AC_DEFINE(HAVE_LIBSTDCXX_DEMANGLER, 1, - [Define if the std c++ library provides a demangler conforming - to the GCC libstdc++ interface.]) - ], - [ - AC_MSG_RESULT(no) - ]) -]) diff --git a/deal.II/contrib/cmake/check/check_for_compiler_features.cmake b/deal.II/contrib/cmake/check/check_for_compiler_features.cmake index 75334b5393..3030edc086 100644 --- a/deal.II/contrib/cmake/check/check_for_compiler_features.cmake +++ b/deal.II/contrib/cmake/check/check_for_compiler_features.cmake @@ -24,3 +24,142 @@ CHECK_CXX_SOURCE_COMPILES( IF(NOT DEAL_II_VECTOR_ITERATOR_IS_NOT_POINTER) SET(DEAL_II_VECTOR_ITERATOR_IS_POINTER TRUE) ENDIF() + + + +# +# Check for existence of the __builtin_expect facility of newer +# gcc compilers. This can be used to hint the compiler's branch +# prediction unit in some cases. We use it in the AssertThrow +# macros. +# +CHECK_CXX_SOURCE_COMPILES( + " + bool f() {} + int main(){ if (__builtin_expect(f(),false)) ; } + " + HAVE_BUILTIN_EXPECT) + + + +# +# Newer versions of gcc have a very nice feature: you can set +# a verbose terminate handler, that not only aborts a program +# when an exception is thrown and not caught somewhere, but +# before aborting it prints that an exception has been thrown, +# and possibly what the std::exception::what() function has to +# say. Since many people run into the trap of not having a +# catch clause in main(), they wonder where that abort may be +# coming from. The terminate handler then at least says what is +# missing in their program. +# +# This test checks whether this feature is available. +# +CHECK_CXX_SOURCE_COMPILES( + " + #include + namespace __gnu_cxx + { + extern void __verbose_terminate_handler (); + } + struct preload_terminate_dummy + { + preload_terminate_dummy() + { + std::set_terminate (__gnu_cxx::__verbose_terminate_handler); + } + }; + static preload_terminate_dummy dummy; + int main() { throw 1; return 0; } + " + HAVE_VERBOSE_TERMINATE) + + + +# +# Check whether glibc-like stacktrace information is available +# for the Exception class. If it is, then try to also determine +# whether the compiler accepts the -rdynamic flag, since that is +# recommended for linking if one wants to have meaningful +# backtraces. +# +CHECK_CXX_SOURCE_COMPILES( + " + #include + #include + void * array[25]; + int nSize = backtrace(array, 25); + char ** symbols = backtrace_symbols(array, nSize); + int main(){ free(symbols); return 0; } + " + HAVE_GLIBC_STACKTRACE) + +# On Mac OS X, -rdynamic is accepted by the compiler (i.e. +# it doesn't produce an error) but we always get a warning +# that it isn't supported. That's pretty stupid because +# we can't test for it. Consequently, only run the test +# if not on OS X. + +IF(HAVE_GLIBC_STACKTRACE AND NOT CMAKE_SYSTEM_NAME MATCHES "Darwin") + + LIST(APPEND CMAKE_REQUIRED_FLAGS "-rdynamic") + + CHECK_CXX_SOURCE_COMPILES( + " + int main() { return 0; } + " + DEAL_II_COMPILER_HAS_RDYNAMIC) + + LIST(REMOVE_ITEM CMAKE_REQUIRED_FLAGS "-rdynamic") + + IF(DEAL_II_COMPILER_HAS_RDYNAMIC) + SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -rdynamic") + ENDIF() + +ENDIF() + + + +# +# Check whether the compiler offers a way to demangle symbols +# from within the program. Used inside the exception stacktrace +# mechanism. +# +# The example code is taken from +# http://gcc.gnu.org/onlinedocs/libstdc++/18_support/howto.html#6 +# +CHECK_CXX_SOURCE_COMPILES( + " + #include + #include + #include + #include + + struct empty { }; + + template + struct bar { }; + + int status; + char *realname; + + int main() + { + // exception classes not in , thrown by the implementation + // instead of the user + std::bad_exception e; + realname = abi::__cxa_demangle(e.what(), 0, 0, &status); + free(realname); + + + // typeid + bar u; + const std::type_info &ti = typeid(u); + + realname = abi::__cxa_demangle(ti.name(), 0, 0, &status); + free(realname); + + return 0; + } + " + HAVE_LIBSTDCXX_DEMANGLER) diff --git a/deal.II/include/deal.II/base/config.h.in b/deal.II/include/deal.II/base/config.h.in index a6ee14203b..5428ceb97f 100644 --- a/deal.II/include/deal.II/base/config.h.in +++ b/deal.II/include/deal.II/base/config.h.in @@ -165,6 +165,20 @@ /* Defined if vector iterators are just plain pointers */ #cmakedefine DEAL_II_VECTOR_ITERATOR_IS_POINTER +/* Define if the compiler provides __builtin_expect */ +#cmakedefine HAVE_BUILTIN_EXPECT + +/* Define if the compiler provides __verbose_terminate_handler */ +#cmakedefine HAVE_VERBOSE_TERMINATE + +/* Define if deal.II is linked against a libc that provides stacktrace debug + information that can be printed out in the exception class */ +#cmakedefine HAVE_GLIBC_STACKTRACE + +/* Defined if the std c++ library provides a demangler conforming to the GCC + libstdc++ interface. */ +#cmakedefine HAVE_LIBSTDCXX_DEMANGLER + diff --git a/deal.II/include/deal.II/base/config.h.in.old b/deal.II/include/deal.II/base/config.h.in.old index 2a5b16917c..4b563eb0e9 100644 --- a/deal.II/include/deal.II/base/config.h.in.old +++ b/deal.II/include/deal.II/base/config.h.in.old @@ -222,9 +222,6 @@ /* Define to 1 if you have the header file. */ #cmakedefine HAVE_AZTECOO_OPERATOR_H -/* Define if the compiler provides __builtin_expect */ -#cmakedefine HAVE_BUILTIN_EXPECT - /* Define to 1 if you have the `daxpy_' function. */ #cmakedefine HAVE_DAXPY_ @@ -315,10 +312,6 @@ /* Define to 1 if you have the `getpid' function. */ #cmakedefine HAVE_GETPID -/* Define if deal.II is linked against a libc that provides stacktrace debug - information that can be printed out in the exception class */ -#cmakedefine HAVE_GLIBC_STACKTRACE - /* Availability of the MA27 algorithm from HSL */ #cmakedefine HAVE_HSL_MA27 @@ -334,11 +327,6 @@ /* Define to 1 if you have the `jn' function. */ #cmakedefine HAVE_JN -/* Define if the std c++ library provides a demangler conforming to the GCC - libstdc++ interface. */ -#cmakedefine HAVE_LIBSTDCXX_DEMANGLER - - /* Define to 1 if you have the header file. */ #cmakedefine HAVE_MEMORY_H @@ -420,9 +408,6 @@ /* Define to 1 if you have the header file. */ #cmakedefine HAVE_UNISTD_H -/* Define if the compiler provides __verbose_terminate_handler */ -#cmakedefine HAVE_VERBOSE_TERMINATE - /* On SunOS 4.x, the getrusage() function exists, but is not declared in the respective header file , as one would think when reading the man pages. Then we have to declare this function ourselves in those files -- 2.39.5