summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--config_host.mk.in1
-rw-r--r--configure.in35
-rw-r--r--sal/inc/rtl/string.hxx18
-rw-r--r--sal/qa/rtl/strings/test_ostring_stringliterals.cxx12
-rw-r--r--sal/rtl/source/strtmpl.cxx1
-rw-r--r--solenv/gbuild/platform/macosx.mk5
-rw-r--r--solenv/gbuild/platform/unxgcc.mk6
-rw-r--r--solenv/inc/unxgcc.mk4
-rw-r--r--solenv/inc/unxmacx.mk3
-rw-r--r--solenv/inc/unxsogi.mk4
-rw-r--r--solenv/inc/unxsogs.mk4
11 files changed, 88 insertions, 5 deletions
diff --git a/config_host.mk.in b/config_host.mk.in
index 2839b5c83eed..77d149871c11 100644
--- a/config_host.mk.in
+++ b/config_host.mk.in
@@ -187,6 +187,7 @@ export HAVE_GCC_AVX=@HAVE_GCC_AVX@
export HAVE_GCC_NO_LONG_DOUBLE=@HAVE_GCC_NO_LONG_DOUBLE@
export HAVE_GCC_VISIBILITY_BROKEN=@HAVE_GCC_VISIBILITY_BROKEN@
export HAVE_GCC_VISIBILITY_FEATURE=@HAVE_GCC_VISIBILITY_FEATURE@
+export HAVE_SFINAE_ANONYMOUS_BROKEN=@HAVE_SFINAE_ANONYMOUS_BROKEN@
export HAVE_GETOPT=@HAVE_GETOPT@
export HAVE_LD_BSYMBOLIC_FUNCTIONS=@HAVE_LD_BSYMBOLIC_FUNCTIONS@
export HAVE_LD_HASH_STYLE=@HAVE_LD_HASH_STYLE@
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])
diff --git a/sal/inc/rtl/string.hxx b/sal/inc/rtl/string.hxx
index 6590677efea0..79b9a15ae94a 100644
--- a/sal/inc/rtl/string.hxx
+++ b/sal/inc/rtl/string.hxx
@@ -85,6 +85,7 @@ namespace rtl
use this class.
*/
+#ifndef HAVE_SFINAE_ANONYMOUS_BROKEN
namespace internal
{
// This template is used for SFINAE (Substitution failure is not an error), to detect that
@@ -107,6 +108,7 @@ struct CharPtrDetector< char* >
typedef Dummy Type;
};
}
+#endif
class OString
{
@@ -184,6 +186,17 @@ public:
@param value a NULL-terminated character array.
*/
+#ifdef HAVE_SFINAE_ANONYMOUS_BROKEN
+ // Old gcc can try to convert anonymous enums to OString and give compile error.
+ // So there's no special-cased handling of string literals.
+ // These are inline functions and technically both variants should work
+ // the same in practice, so there should be no compatibility problem.
+ OString( const sal_Char * value ) SAL_THROW(())
+ {
+ pData = 0;
+ rtl_string_newFromStr( &pData, value );
+ }
+#else
template< typename T >
OString( const T& value, typename internal::CharPtrDetector< T >::Type = internal::Dummy() ) SAL_THROW(())
{
@@ -194,8 +207,8 @@ public:
/**
New string from a string literal.
- Note that embedded \0's are included in the string if explicitly present
- in the string literal.
+ If there are any embedded \0's in the string literal, the result is undefined.
+ Use the overload that explicitly accepts length.
@param literal a string literal
*/
@@ -221,6 +234,7 @@ public:
pData = 0;
rtl_string_newFromStr( &pData, value );
}
+#endif // HAVE_SFINAE_ANONYMOUS_BROKEN
/**
New string from a character buffer array.
diff --git a/sal/qa/rtl/strings/test_ostring_stringliterals.cxx b/sal/qa/rtl/strings/test_ostring_stringliterals.cxx
index 22f79ab630a6..8398ae9e63e9 100644
--- a/sal/qa/rtl/strings/test_ostring_stringliterals.cxx
+++ b/sal/qa/rtl/strings/test_ostring_stringliterals.cxx
@@ -62,6 +62,8 @@ CPPUNIT_TEST_SUITE_END();
void test::ostring::StringLiterals::checkCtors()
{
+// string literal ctors do not work with SFINAE broken and are disabled
+#ifndef HAVE_SFINAE_ANONYMOUS_BROKEN
CPPUNIT_ASSERT( CONST_CTOR_USED( "test" ));
const char good1[] = "test";
CPPUNIT_ASSERT( CONST_CTOR_USED( good1 ));
@@ -89,13 +91,19 @@ void test::ostring::StringLiterals::checkCtors()
CPPUNIT_ASSERT( rtl::OString( (const char*)"ab" ) == rtl::OString( "ab" ));
// Check that contents are correct and equal to the case when RTL_CONSTASCII_STRINGPARAM is used.
+ CPPUNIT_ASSERT( rtl::OString( RTL_CONSTASCII_STRINGPARAM( "" )) == rtl::OString( "" ));
+ CPPUNIT_ASSERT( rtl::OString( RTL_CONSTASCII_STRINGPARAM( "ab" )) == rtl::OString( "ab" ));
+#if 0
+// This is currently disabled because it can't be consistent with HAVE_SFINAE_ANONYMOUS_BROKEN.
+// Since the situation wasn't quite consistent even before, there should be no big harm.
+
// Check also that embedded \0 is included (RTL_CONSTASCII_STRINGPARAM does the same,
// const char* ctor does not, but it seems to make more sense to include it when
// it's explicitly mentioned in the string literal).
- CPPUNIT_ASSERT( rtl::OString( RTL_CONSTASCII_STRINGPARAM( "" )) == rtl::OString( "" ));
CPPUNIT_ASSERT( rtl::OString( RTL_CONSTASCII_STRINGPARAM( "\0" )) == rtl::OString( "\0" ));
- CPPUNIT_ASSERT( rtl::OString( RTL_CONSTASCII_STRINGPARAM( "ab" )) == rtl::OString( "ab" ));
CPPUNIT_ASSERT( rtl::OString( RTL_CONSTASCII_STRINGPARAM( "a\0b" )) == rtl::OString( "a\0b" ));
+#endif
+#endif
}
void test::ostring::StringLiterals::testcall( const char str[] )
diff --git a/sal/rtl/source/strtmpl.cxx b/sal/rtl/source/strtmpl.cxx
index a3ef1facdadf..2d8c44bbe4fa 100644
--- a/sal/rtl/source/strtmpl.cxx
+++ b/sal/rtl/source/strtmpl.cxx
@@ -1189,7 +1189,6 @@ void SAL_CALL IMPL_RTL_STRINGNAME( newFromStr_WithLength )( IMPL_RTL_STRINGDATA*
/* ----------------------------------------------------------------------- */
// Used when creating from string literals.
-// Intentionally copies also embedded \0's if present.
void SAL_CALL IMPL_RTL_STRINGNAME( newFromLiteral)( IMPL_RTL_STRINGDATA** ppThis,
const sal_Char* pCharStr,
sal_Int32 nLen )
diff --git a/solenv/gbuild/platform/macosx.mk b/solenv/gbuild/platform/macosx.mk
index 9a918246f738..22a1fa8e94d9 100644
--- a/solenv/gbuild/platform/macosx.mk
+++ b/solenv/gbuild/platform/macosx.mk
@@ -51,6 +51,11 @@ gb_COMPILERDEFS += \
-DHAVE_GCC_VISIBILITY_FEATURE \
+ifeq ($(HAVE_SFINAE_ANONYMOUS_BROKEN),TRUE)
+gb_COMPILERDEFS += \
+ -DHAVE_SFINAE_ANONYMOUS_BROKEN \
+
+endif
gb_CFLAGS := \
-isysroot $(gb_SDKDIR) \
diff --git a/solenv/gbuild/platform/unxgcc.mk b/solenv/gbuild/platform/unxgcc.mk
index c709fde1e4e8..43f58a7cf0b4 100644
--- a/solenv/gbuild/platform/unxgcc.mk
+++ b/solenv/gbuild/platform/unxgcc.mk
@@ -84,6 +84,12 @@ endif
endif
+ifeq ($(HAVE_SFINAE_ANONYMOUS_BROKEN),TRUE)
+gb_COMPILERDEFS += \
+ -DHAVE_SFINAE_ANONYMOUS_BROKEN \
+
+endif
+
# enable debug STL
ifeq ($(gb_PRODUCT),$(false))
gb_COMPILERDEFS += \
diff --git a/solenv/inc/unxgcc.mk b/solenv/inc/unxgcc.mk
index 3765b2dd6cea..8bfeebc20cf6 100644
--- a/solenv/inc/unxgcc.mk
+++ b/solenv/inc/unxgcc.mk
@@ -51,6 +51,10 @@ CDEFS+=-D_PTHREADS -D_REENTRANT -DNEW_SOLAR -D_USE_NAMESPACE=1
CDEFS += -DHAVE_GCC_VISIBILITY_FEATURE
.ENDIF # "$(HAVE_GCC_VISIBILITY_FEATURE)" == "TRUE"
+.IF "$(HAVE_SFINAE_ANONYMOUS_BROKEN)" == "TRUE"
+CDEFS += -DHAVE_SFINAE_ANONYMOUS_BROKEN
+.ENDIF # "$(HAVE_SFINAE_ANONYMOUS_BROKEN)" == "TRUE"
+
# this is a platform with JAVA support
.IF "$(SOLAR_JAVA)"!=""
JAVADEF=-DSOLAR_JAVA
diff --git a/solenv/inc/unxmacx.mk b/solenv/inc/unxmacx.mk
index 0cb0b62ee02f..8f36772f4d06 100644
--- a/solenv/inc/unxmacx.mk
+++ b/solenv/inc/unxmacx.mk
@@ -60,6 +60,9 @@ EXTRA_CDEFS+:=-isysroot $(MACOSX_SDK_PATH) -DMAC_OS_X_VERSION_MIN_REQUIRED=$(MA
CDEFS += -DHAVE_GCC_VISIBILITY_FEATURE
.ENDIF # "$(HAVE_GCC_VISIBILITY_FEATURE)" == "TRUE"
+.IF "$(HAVE_SFINAE_ANONYMOUS_BROKEN)" == "TRUE"
+CDEFS += -DHAVE_SFINAE_ANONYMOUS_BROKEN
+.ENDIF # "$(HAVE_SFINAE_ANONYMOUS_BROKEN)" == "TRUE"
# MacOS X specific Java compilation/link flags
SOLAR_JAVA*=TRUE
diff --git a/solenv/inc/unxsogi.mk b/solenv/inc/unxsogi.mk
index 2ebcbc468e42..4e811655bfd3 100644
--- a/solenv/inc/unxsogi.mk
+++ b/solenv/inc/unxsogi.mk
@@ -94,6 +94,10 @@ LINKVERSIONMAPFLAG=-Wl,--version-script
CDEFS += -DHAVE_GCC_VISIBILITY_FEATURE
.ENDIF # "$(HAVE_GCC_VISIBILITY_FEATURE)" == "TRUE"
+.IF "$(HAVE_SFINAE_ANONYMOUS_BROKEN)" == "TRUE"
+CDEFS += -DHAVE_SFINAE_ANONYMOUS_BROKEN
+.ENDIF # "$(HAVE_SFINAE_ANONYMOUS_BROKEN)" == "TRUE"
+
# Reihenfolge der libs NICHT egal!
STDLIBCPP=-lstdc++
diff --git a/solenv/inc/unxsogs.mk b/solenv/inc/unxsogs.mk
index 4f80b42c0a4a..e25d690ce49f 100644
--- a/solenv/inc/unxsogs.mk
+++ b/solenv/inc/unxsogs.mk
@@ -93,6 +93,10 @@ LINKVERSIONMAPFLAG=-Wl,--version-script
CDEFS += -DHAVE_GCC_VISIBILITY_FEATURE
.ENDIF # "$(HAVE_GCC_VISIBILITY_FEATURE)" == "TRUE"
+.IF "$(HAVE_SFINAE_ANONYMOUS_BROKEN)" == "TRUE"
+CDEFS += -DHAVE_SFINAE_ANONYMOUS_BROKEN
+.ENDIF # "$(HAVE_SFINAE_ANONYMOUS_BROKEN)" == "TRUE"
+
# Reihenfolge der libs NICHT egal!
STDLIBCPP=-lstdc++