summaryrefslogtreecommitdiff
path: root/configure.in
diff options
context:
space:
mode:
authorLuboš Luňák <l.lunak@suse.cz>2012-03-13 16:09:25 +0100
committerLuboš Luňák <l.lunak@suse.cz>2012-03-13 16:21:04 +0100
commit3d9f5c856a4a77503695e68ce013ebf859fcb212 (patch)
treeaaa75452b54542a52f746da9782ae6c3d2663453 /configure.in
parent131e5d35a4edb9f8875a197e8e0382c168834f70 (diff)
make OString work even with old gcc that has SFINAE broken
Since OString already has a ctor accepting const char*, I cannot find out a way to distinguish string literals other than using a template, otherwise const char* somehow takes precedence (all of gcc, clang, msvc). But the template requires the Substitution Is Not A Failure Idiom to actually create only wanted instances. And the compiler can try evaluate the OString ctor as a possibility when comparing an int to an anonymous enum, and anonymous enum as a type without linkage cannot be a template argument before C++11. SFINAE should still work, but not with gcc older than 4.0.2 (which we right now use only on macs). So for that case disable the string literal ctors, which means macs will have one extra strlen call, and also that embedded \0's in string literals will be inconsistent. The tiny performance problem shouldn't matter that much and will eventually go away, the \0 problem should not matter, since before string literal ctors were introduced \0's had not been included anyway unless RTL_CONSTASCII_STRINGPARAM was used. So we should be safe and when removing the CONSTASCII macros \0 cases should be handled by explicitly mentioning the length.
Diffstat (limited to 'configure.in')
-rw-r--r--configure.in35
1 files changed, 35 insertions, 0 deletions
diff --git a/configure.in b/configure.in
index 764b9c00a827..e0bc4ddb2b24 100644
--- a/configure.in
+++ b/configure.in
@@ -4559,6 +4559,41 @@ AC_SUBST(HAVE_GCC_VISIBILITY_FEATURE)
AC_SUBST(HAVE_GCC_VISIBILITY_BROKEN)
dnl ===================================================================
+dnl SFINAE test
+dnl Pre-C++11 does not allow types without linkage as template arguments.
+dnl Substitution Failure Is Not An Error is an idiom that disables
+dnl template instances that would cause an error, without actually
+dnl causing an error. Old gcc (pre-4.0.2) however causes a real error.
+dnl http://gcc.gnu.org/bugzilla/show_bug.cgi?id=21514
+dnl ===================================================================
+HAVE_SFINAE_ANONYMOUS_BROKEN=
+if test \( "$_os" != "WINNT" -o "$WITH_MINGW" = "yes" \); then
+
+ AC_LANG_PUSH([C++])
+ AC_MSG_CHECKING([if SFINAE is broken with anonymous types])
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+enum { AnonymousEnumValue };
+template< typename T > class TestPredicate {};
+template<> class TestPredicate< int > { public: typedef bool Type; };
+template< typename T >
+bool test( const T&, typename TestPredicate< T >::Type = false )
+ { return true; };
+void test( ... );
+ ]], [[
+ test( 10 );
+ test( AnonymousEnumValue );
+ ]])],[sfinae_anonymous_broken=no],[sfinae_anonymous_broken=yes
+ ])
+ AC_MSG_RESULT([$sfinae_anonymous_broken])
+ if test "$sfinae_anonymous_broken" = "yes"; then
+ HAVE_SFINAE_ANONYMOUS_BROKEN="TRUE"
+ fi
+ AC_LANG_POP([C++])
+fi
+
+AC_SUBST(HAVE_SFINAE_ANONYMOUS_BROKEN)
+
+dnl ===================================================================
dnl allocator
dnl ===================================================================
AC_MSG_CHECKING([which memory allocator to use])