Replace my previous incorrect fix for |operator==| ambiguities with a correct one: provide additional |operator==| and |operator!=| for comparing nsCOMPtrs to raw pointers that take a non-const raw pointer argument so that builtin operators will not have a better conversion for one argument. b=65664 r=waterson@netscape.com sr=scc@mozilla.org

This commit is contained in:
dbaron%fas.harvard.edu 2001-04-07 15:29:39 +00:00
parent 3aad2295ca
commit 780cb86a7a
3 changed files with 88 additions and 67 deletions

View File

@ -3487,35 +3487,6 @@ if test "$_PEDANTIC"; then
esac
fi
dnl Bug 65664: gcc (with -pedantic) and HP's aCC (with +p) have
dnl problems resolving ambiguities with some of the operator== in
dnl nsCOMPtr.h because they consider the top-level cv-qualifiers in
dnl overload resolution.
AC_LANG_CPLUSPLUS
_SAVE_CXXFLAGS=$CXXFLAGS
CXXFLAGS="$CXXFLAGS ${_WARNINGS_CXXFLAGS}"
AC_CACHE_CHECK(for bug where toplevel cv-qualifiers are used in overload resolution,
ac_cv_quals_ambig_bug,
[AC_TRY_COMPILE([
inline int f(void *p, int *q) { return 1; }
inline int f(int *p, const int *q) { return 0; }
],
[
int *a = 0;
return f(a, a); // should choose int f(int*, const int*)
],
ac_cv_quals_ambig_bug="no",
ac_cv_quals_ambig_bug="yes")])
AC_LANG_C
CXXFLAGS="$_SAVE_CXXFLAGS"
if test "$ac_cv_quals_ambig_bug" = "yes" ; then
AC_DEFINE(CPP_CV_QUALIFIERS_CAUSE_AMBIGUITY)
fi
dnl pass -Wno-long-long to the compiler
MOZ_ARG_ENABLE_BOOL(long-long-warning,
[ --enable-long-long-warning

View File

@ -1153,27 +1153,12 @@ operator!=( const nsCOMPtr<T>& lhs, const nsCOMPtr<U>& rhs )
}
// Some compilers incorrectly consider the top-level cv-qualifiers in
// overload resolution. This leads to ambiguities with builtin
// |operator==| because the |const| makes the |operator==|
// defined here, which would otherwise have a better or equally
// good conversion for all parameters, have a worse conversion
// for one parameter because of the |const|. Since the |const|'s
// only purpose is to make the argument |const| when used within
// the function, we'll remove it for those compilers since we know
// we're doing the right thing anyway. See bug 65664 for details.
#ifdef CPP_CV_QUALIFIERS_CAUSE_AMBIGUITY
#define NSCAP_CONST_PARAM
#else
#define NSCAP_CONST_PARAM const
#endif
// Comparing an |nsCOMPtr| to a raw pointer
template <class T, class U>
inline
NSCAP_BOOL
operator==( NSCAP_CONST_PARAM nsCOMPtr<T>& lhs, NSCAP_CONST_PARAM U* rhs )
operator==( const nsCOMPtr<T>& lhs, const U* rhs )
{
return NS_STATIC_CAST(const void*, lhs.get()) == NS_STATIC_CAST(const void*, rhs);
}
@ -1181,7 +1166,7 @@ operator==( NSCAP_CONST_PARAM nsCOMPtr<T>& lhs, NSCAP_CONST_PARAM U* rhs )
template <class T, class U>
inline
NSCAP_BOOL
operator==( NSCAP_CONST_PARAM U* lhs, NSCAP_CONST_PARAM nsCOMPtr<T>& rhs )
operator==( const U* lhs, const nsCOMPtr<T>& rhs )
{
return NS_STATIC_CAST(const void*, lhs) == NS_STATIC_CAST(const void*, rhs.get());
}
@ -1189,7 +1174,7 @@ operator==( NSCAP_CONST_PARAM U* lhs, NSCAP_CONST_PARAM nsCOMPtr<T>& rhs )
template <class T, class U>
inline
NSCAP_BOOL
operator!=( NSCAP_CONST_PARAM nsCOMPtr<T>& lhs, NSCAP_CONST_PARAM U* rhs )
operator!=( const nsCOMPtr<T>& lhs, const U* rhs )
{
return NS_STATIC_CAST(const void*, lhs.get()) != NS_STATIC_CAST(const void*, rhs);
}
@ -1197,11 +1182,51 @@ operator!=( NSCAP_CONST_PARAM nsCOMPtr<T>& lhs, NSCAP_CONST_PARAM U* rhs )
template <class T, class U>
inline
NSCAP_BOOL
operator!=( NSCAP_CONST_PARAM U* lhs, NSCAP_CONST_PARAM nsCOMPtr<T>& rhs )
operator!=( const U* lhs, const nsCOMPtr<T>& rhs )
{
return NS_STATIC_CAST(const void*, lhs) != NS_STATIC_CAST(const void*, rhs.get());
}
// To avoid ambiguities caused by the presence of builtin |operator==|s
// creating a situation where one of the |operator==| defined above
// has a better conversion for one argument and the builtin has a
// better conversion for the other argument, define additional
// |operator==| without the |const| on the raw pointer.
// See bug 65664 for details.
#ifndef CANT_RESOLVE_CPP_CONST_AMBIGUITY
template <class T, class U>
inline
NSCAP_BOOL
operator==( const nsCOMPtr<T>& lhs, U* rhs )
{
return NS_STATIC_CAST(const void*, lhs.get()) == NS_STATIC_CAST(void*, rhs);
}
template <class T, class U>
inline
NSCAP_BOOL
operator==( U* lhs, const nsCOMPtr<T>& rhs )
{
return NS_STATIC_CAST(void*, lhs) == NS_STATIC_CAST(const void*, rhs.get());
}
template <class T, class U>
inline
NSCAP_BOOL
operator!=( const nsCOMPtr<T>& lhs, U* rhs )
{
return NS_STATIC_CAST(const void*, lhs.get()) != NS_STATIC_CAST(void*, rhs);
}
template <class T, class U>
inline
NSCAP_BOOL
operator!=( U* lhs, const nsCOMPtr<T>& rhs )
{
return NS_STATIC_CAST(void*, lhs) != NS_STATIC_CAST(const void*, rhs.get());
}
#endif
// Comparing an |nsCOMPtr| to |0|

View File

@ -1153,27 +1153,12 @@ operator!=( const nsCOMPtr<T>& lhs, const nsCOMPtr<U>& rhs )
}
// Some compilers incorrectly consider the top-level cv-qualifiers in
// overload resolution. This leads to ambiguities with builtin
// |operator==| because the |const| makes the |operator==|
// defined here, which would otherwise have a better or equally
// good conversion for all parameters, have a worse conversion
// for one parameter because of the |const|. Since the |const|'s
// only purpose is to make the argument |const| when used within
// the function, we'll remove it for those compilers since we know
// we're doing the right thing anyway. See bug 65664 for details.
#ifdef CPP_CV_QUALIFIERS_CAUSE_AMBIGUITY
#define NSCAP_CONST_PARAM
#else
#define NSCAP_CONST_PARAM const
#endif
// Comparing an |nsCOMPtr| to a raw pointer
template <class T, class U>
inline
NSCAP_BOOL
operator==( NSCAP_CONST_PARAM nsCOMPtr<T>& lhs, NSCAP_CONST_PARAM U* rhs )
operator==( const nsCOMPtr<T>& lhs, const U* rhs )
{
return NS_STATIC_CAST(const void*, lhs.get()) == NS_STATIC_CAST(const void*, rhs);
}
@ -1181,7 +1166,7 @@ operator==( NSCAP_CONST_PARAM nsCOMPtr<T>& lhs, NSCAP_CONST_PARAM U* rhs )
template <class T, class U>
inline
NSCAP_BOOL
operator==( NSCAP_CONST_PARAM U* lhs, NSCAP_CONST_PARAM nsCOMPtr<T>& rhs )
operator==( const U* lhs, const nsCOMPtr<T>& rhs )
{
return NS_STATIC_CAST(const void*, lhs) == NS_STATIC_CAST(const void*, rhs.get());
}
@ -1189,7 +1174,7 @@ operator==( NSCAP_CONST_PARAM U* lhs, NSCAP_CONST_PARAM nsCOMPtr<T>& rhs )
template <class T, class U>
inline
NSCAP_BOOL
operator!=( NSCAP_CONST_PARAM nsCOMPtr<T>& lhs, NSCAP_CONST_PARAM U* rhs )
operator!=( const nsCOMPtr<T>& lhs, const U* rhs )
{
return NS_STATIC_CAST(const void*, lhs.get()) != NS_STATIC_CAST(const void*, rhs);
}
@ -1197,11 +1182,51 @@ operator!=( NSCAP_CONST_PARAM nsCOMPtr<T>& lhs, NSCAP_CONST_PARAM U* rhs )
template <class T, class U>
inline
NSCAP_BOOL
operator!=( NSCAP_CONST_PARAM U* lhs, NSCAP_CONST_PARAM nsCOMPtr<T>& rhs )
operator!=( const U* lhs, const nsCOMPtr<T>& rhs )
{
return NS_STATIC_CAST(const void*, lhs) != NS_STATIC_CAST(const void*, rhs.get());
}
// To avoid ambiguities caused by the presence of builtin |operator==|s
// creating a situation where one of the |operator==| defined above
// has a better conversion for one argument and the builtin has a
// better conversion for the other argument, define additional
// |operator==| without the |const| on the raw pointer.
// See bug 65664 for details.
#ifndef CANT_RESOLVE_CPP_CONST_AMBIGUITY
template <class T, class U>
inline
NSCAP_BOOL
operator==( const nsCOMPtr<T>& lhs, U* rhs )
{
return NS_STATIC_CAST(const void*, lhs.get()) == NS_STATIC_CAST(void*, rhs);
}
template <class T, class U>
inline
NSCAP_BOOL
operator==( U* lhs, const nsCOMPtr<T>& rhs )
{
return NS_STATIC_CAST(void*, lhs) == NS_STATIC_CAST(const void*, rhs.get());
}
template <class T, class U>
inline
NSCAP_BOOL
operator!=( const nsCOMPtr<T>& lhs, U* rhs )
{
return NS_STATIC_CAST(const void*, lhs.get()) != NS_STATIC_CAST(void*, rhs);
}
template <class T, class U>
inline
NSCAP_BOOL
operator!=( U* lhs, const nsCOMPtr<T>& rhs )
{
return NS_STATIC_CAST(void*, lhs) != NS_STATIC_CAST(const void*, rhs.get());
}
#endif
// Comparing an |nsCOMPtr| to |0|