diff options
author | Paolo Carlini <paolo.carlini@oracle.com> | 2010-07-12 19:59:31 +0000 |
---|---|---|
committer | Paolo Carlini <paolo@gcc.gnu.org> | 2010-07-12 19:59:31 +0000 |
commit | 248ce2f8d14c044c9c540a02f112c521a2e616b0 (patch) | |
tree | 549fbd7f45b4c2063e6078f170a0a31b1abddd5a /gcc | |
parent | ac9b0eeae0cd0d51908039aae35d1dff6a1486aa (diff) | |
download | gcc-248ce2f8d14c044c9c540a02f112c521a2e616b0.zip gcc-248ce2f8d14c044c9c540a02f112c521a2e616b0.tar.gz gcc-248ce2f8d14c044c9c540a02f112c521a2e616b0.tar.bz2 |
re PR c++/44907 (SFINAE vs ambiguous base (the real one ;))
/cp
2010-07-12 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/44907
* call.c (build_temp): Add tsubst_flags_t complain parameter;
adjust build_special_member_call call, pass complain.
(convert_like_real): Adjust build_temp call, pass complain.
/testsuite
2010-07-12 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/44907
* g++.dg/template/sfinae19.C: New.
* g++.dg/template/sfinae20.C: Likewise.
From-SVN: r162113
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/cp/call.c | 8 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/sfinae19.C | 44 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/sfinae20.C | 45 |
5 files changed, 106 insertions, 4 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index bdae8fc..27061ad 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2010-07-12 Paolo Carlini <paolo.carlini@oracle.com> + + PR c++/44907 + * call.c (build_temp): Add tsubst_flags_t complain parameter; + adjust build_special_member_call call, pass complain. + (convert_like_real): Adjust build_temp call, pass complain. + 2010-07-09 Jason Merrill <jason@redhat.com> PR c++/43120 diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 0bf7b8e..ca34a6c 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -204,7 +204,7 @@ static void add_candidates (tree, tree, const VEC(tree,gc) *, tree, tree, bool, tree, tree, int, struct z_candidate **); static conversion *merge_conversion_sequences (conversion *, conversion *); static bool magic_varargs_p (tree); -static tree build_temp (tree, tree, int, diagnostic_t *); +static tree build_temp (tree, tree, int, diagnostic_t *, tsubst_flags_t); /* Returns nonzero iff the destructor name specified in NAME matches BASETYPE. NAME can take many forms... */ @@ -4851,7 +4851,7 @@ enforce_access (tree basetype_path, tree decl, tree diag_decl) static tree build_temp (tree expr, tree type, int flags, - diagnostic_t *diagnostic_kind) + diagnostic_t *diagnostic_kind, tsubst_flags_t complain) { int savew, savee; VEC(tree,gc) *args; @@ -4859,7 +4859,7 @@ build_temp (tree expr, tree type, int flags, savew = warningcount, savee = errorcount; args = make_tree_vector_single (expr); expr = build_special_member_call (NULL_TREE, complete_ctor_identifier, - &args, type, flags, tf_warning_or_error); + &args, type, flags, complain); release_tree_vector (args); if (warningcount > savew) *diagnostic_kind = DK_WARNING; @@ -5132,7 +5132,7 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum, conversion (i.e. the second step of copy-initialization), so don't allow any more. */ flags |= LOOKUP_NO_CONVERSION; - expr = build_temp (expr, totype, flags, &diag_kind); + expr = build_temp (expr, totype, flags, &diag_kind, complain); if (diag_kind && fn) { if ((complain & tf_error)) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 7d0fb14..f987058 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2010-07-12 Paolo Carlini <paolo.carlini@oracle.com> + + PR c++/44907 + * g++.dg/template/sfinae19.C: New. + * g++.dg/template/sfinae20.C: Likewise. + 2010-07-12 Jie Zhang <jie@codesourcery.com> * gcc.target/arm/interrupt-1.c: New test. diff --git a/gcc/testsuite/g++.dg/template/sfinae19.C b/gcc/testsuite/g++.dg/template/sfinae19.C new file mode 100644 index 0000000..59be183 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/sfinae19.C @@ -0,0 +1,44 @@ +// PR c++/44907 + +struct A { }; + +struct B +: public A { }; + +struct C +: public A { }; + +struct D +: public B, public C { }; + +template<bool, typename T = void> struct enable_if { typedef T type; }; +template<typename T> struct enable_if<false, T> { }; + +template<typename From, typename To> + class mini_is_convertible + { + typedef char one; + typedef struct { char arr[2]; } two; + + template<typename To1> + static void test_aux(To1); + + template<typename To1, typename From1> + static typename + enable_if<(sizeof(test_aux<To1>(From1()), 1) > 0), one>::type + test(int); + + template<typename, typename> + static two test(...); + + public: + static const bool value = sizeof(test<To, From>(0)) == 1; + }; + +template<typename From, typename To> + const bool mini_is_convertible<From, To>::value; + +int Test1[mini_is_convertible<D*, A*>::value ? -1 : 1]; +int Test2[mini_is_convertible<A*, D*>::value ? -1 : 1]; +int Test3[mini_is_convertible<D, A>::value ? -1 : 1]; +int Test4[mini_is_convertible<A, D>::value ? -1 : 1]; diff --git a/gcc/testsuite/g++.dg/template/sfinae20.C b/gcc/testsuite/g++.dg/template/sfinae20.C new file mode 100644 index 0000000..9767bc0 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/sfinae20.C @@ -0,0 +1,45 @@ +// PR c++/44907 +// { dg-options "-std=c++0x" } + +#include <utility> + +struct A { }; + +struct B +: public A { }; + +struct C +: public A { }; + +struct D +: public B, public C { }; + +template<typename From, typename To> + class mini_is_convertible + { + typedef char one; + typedef struct { char arr[2]; } two; + + template<typename To1> + static void test_aux(To1); + + template<typename To1, typename From1> + static decltype(test_aux<To1>(std::declval<From1>()), one()) + test(int); + + template<typename, typename> + static two test(...); + + public: + static const bool value = sizeof(test<To, From>(0)) == 1; + }; + +template<typename From, typename To> + const bool mini_is_convertible<From, To>::value; + +static_assert (!mini_is_convertible<D*, A*>::value, ""); +static_assert (!mini_is_convertible<A*, D*>::value, ""); +static_assert (!mini_is_convertible<D&, A&>::value, ""); +static_assert (!mini_is_convertible<A&, D&>::value, ""); +static_assert (!mini_is_convertible<D, A>::value, ""); +static_assert (!mini_is_convertible<A, D>::value, ""); |