From 2b2a72efcf7c0c35cb8c5000ea163c4de2f15280 Mon Sep 17 00:00:00 2001 From: Wolfgang Bangerth Date: Thu, 1 May 2003 15:27:03 +0000 Subject: [PATCH] Detect yet another compiler bug... git-svn-id: https://svn.dealii.org/trunk@7527 0785d39b-7218-0410-832d-ea1e28bc413d --- deal.II/aclocal.m4 | 62 +++++++++++++++++++++++- deal.II/base/include/base/config.h.in | 4 ++ deal.II/configure | 68 +++++++++++++++++++++++++++ deal.II/configure.in | 1 + 4 files changed, 133 insertions(+), 2 deletions(-) diff --git a/deal.II/aclocal.m4 b/deal.II/aclocal.m4 index caadf3e7f1..80b297582d 100644 --- a/deal.II/aclocal.m4 +++ b/deal.II/aclocal.m4 @@ -2172,8 +2172,8 @@ AC_DEFUN(DEAL_II_CHECK_TEMPLATE_TEMPLATE_TYPEDEF_BUG, dnl dnl ------------------------------------------------------------- -dnl gcc 2.95 does not correctly implement the resolution of -dnl defect report #45 to the C++ standard (see +dnl gcc 2.95 as well as some other compilers do not correctly implement +dnl the resolution of defect report #45 to the C++ standard (see dnl http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/cwg_active.html#45). dnl try to detect this, and set a flag correspondingly. in short, dnl the DR says that this is allowed, since member classes are @@ -2226,6 +2226,64 @@ AC_DEFUN(DEAL_II_CHECK_NESTED_CLASS_FRIEND_BUG, dnl +dnl ------------------------------------------------------------- +dnl gcc up to 3.3 won't accept the following code: +dnl ----------------------------- +dnl template class X { +dnl template class Y {}; +dnl +dnl template +dnl template +dnl friend class X::Y; +dnl }; +dnl +dnl X x; +dnl ----------------------------- +dnl +dnl They don't accept the X::Y here, probably because the class is +dnl not complete at this point. gcc3.4 gets it right, though. One +dnl can work around by simply saying +dnl template friend class Y; +dnl but then icc doesn't understand this :-( So everyone's got a bug +dnl here. Also, note that the standard says that Y is an implicit friend +dnl of X, but again, many compiler don't implement this correctly, which +dnl is why we have to do something like the above in the first place... +dnl +dnl Usage: DEAL_II_CHECK_NESTED_CLASS_TEMPL_FRIEND_BUG +dnl +dnl ------------------------------------------------------------- +AC_DEFUN(DEAL_II_CHECK_NESTED_CLASS_TEMPL_FRIEND_BUG, dnl +[ + AC_MSG_CHECKING(for nested template class friends bug) + AC_LANG(C++) + CXXFLAGS="$CXXFLAGSG" + AC_TRY_COMPILE( + [ + template class X { + template class Y {}; + + template + template + friend class X::Y; + }; + + X x; + ], + [], + [ + AC_MSG_RESULT(no) + ], + [ + AC_MSG_RESULT(yes. using workaround) + AC_DEFINE(DEAL_II_NESTED_CLASS_TEMPL_FRIEND_BUG, 1, + [Defined if the compiler does not understand friend + declarations for nested member classes when giving + a full class specification.]) + ]) +]) + + + dnl ------------------------------------------------------------- dnl Many compilers get this wrong (see Section 14.7.3.1, number (4)): dnl --------------------------------- diff --git a/deal.II/base/include/base/config.h.in b/deal.II/base/include/base/config.h.in index 520ee6b9b1..32d66a866d 100644 --- a/deal.II/base/include/base/config.h.in +++ b/deal.II/base/include/base/config.h.in @@ -97,6 +97,10 @@ friends of the enclosing class. */ #undef DEAL_II_NESTED_CLASS_FRIEND_BUG +/* Defined if the compiler does not understand friend declarations for nested + member classes when giving a full class specification. */ +#undef DEAL_II_NESTED_CLASS_TEMPL_FRIEND_BUG + /* Path to the deal.II directory */ #undef DEAL_II_PATH diff --git a/deal.II/configure b/deal.II/configure index d4b9a7fab1..798eb55df4 100755 --- a/deal.II/configure +++ b/deal.II/configure @@ -4760,6 +4760,74 @@ cat >>confdefs.h <<\_ACEOF _ACEOF +fi +rm -f conftest.$ac_objext conftest.$ac_ext + + + echo "$as_me:$LINENO: checking for nested template class friends bug" >&5 +echo $ECHO_N "checking for nested template class friends bug... $ECHO_C" >&6 + ac_ext=cc +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + + CXXFLAGS="$CXXFLAGSG" + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + + template class X { + template class Y {}; + + template + template + friend class X::Y; + }; + + X x; + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 + +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + + echo "$as_me:$LINENO: result: yes. using workaround" >&5 +echo "${ECHO_T}yes. using workaround" >&6 + +cat >>confdefs.h <<\_ACEOF +#define DEAL_II_NESTED_CLASS_TEMPL_FRIEND_BUG 1 +_ACEOF + + fi rm -f conftest.$ac_objext conftest.$ac_ext diff --git a/deal.II/configure.in b/deal.II/configure.in index ab854ceafb..7ee667b31a 100644 --- a/deal.II/configure.in +++ b/deal.II/configure.in @@ -173,6 +173,7 @@ DEAL_II_CHECK_IMPLEMENTED_PURE_FUNCTION_BUG DEAL_II_CHECK_TEMPLATE_TEMPLATE_TYPEDEF_BUG DEAL_II_CHECK_FUNPTR_TEMPLATE_TEMPLATE_BUG DEAL_II_CHECK_NESTED_CLASS_FRIEND_BUG +DEAL_II_CHECK_NESTED_CLASS_TEMPL_FRIEND_BUG DEAL_II_CHECK_MEMBER_VAR_SPECIALIZATION_BUG DEAL_II_CHECK_LONG_DOUBLE_LOOP_BUG DEAL_II_CHECK_ANON_NAMESPACE_BUG -- 2.39.5