From patchwork Mon Jul 12 15:34:14 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [C++] Fix PR 44907 (SFINAE vs ambiguous base) Date: Mon, 12 Jul 2010 05:34:14 -0000 From: Paolo Carlini X-Patchwork-Id: 58624 Message-Id: <4C3B35F6.2030209@oracle.com> To: "gcc-patches@gcc.gnu.org" Cc: Jason Merrill Hi, this is a fix for the first SFINAE issue noticed while drafting __is_convertible_to. Tested x86_64-linux. Ok for mainline? Thanks, Paolo. /////////////////////// /cp 2010-07-12 Paolo Carlini PR c++/44907 * call.c (build_temp): Add tsubst_flags_t complain parameter; adjust build_special_member_call, pass complain. (convert_like_real): Adjust build_temp call, pass complain. /testsuite 2010-07-12 Paolo Carlini PR c++/44907 * g++.dg/template/sfinae19.C: New. * g++.dg/template/sfinae20.C: Likewise. Index: testsuite/g++.dg/template/sfinae20.C =================================================================== --- testsuite/g++.dg/template/sfinae20.C (revision 0) +++ testsuite/g++.dg/template/sfinae20.C (revision 0) @@ -0,0 +1,45 @@ +// PR c++/44907 +// { dg-options "-std=c++0x" } + +#include + +struct A { }; + +struct B +: public A { }; + +struct C +: public A { }; + +struct D +: public B, public C { }; + +template + class mini_is_convertible + { + typedef char one; + typedef struct { char arr[2]; } two; + + template + static void test_aux(To1); + + template + static decltype(test_aux(std::declval()), one()) + test(int); + + template + static two test(...); + + public: + static const bool value = sizeof(test(0)) == 1; + }; + +template + const bool mini_is_convertible::value; + +static_assert (!mini_is_convertible::value, ""); +static_assert (!mini_is_convertible::value, ""); +static_assert (!mini_is_convertible::value, ""); +static_assert (!mini_is_convertible::value, ""); +static_assert (!mini_is_convertible::value, ""); +static_assert (!mini_is_convertible::value, ""); Index: testsuite/g++.dg/template/sfinae19.C =================================================================== --- testsuite/g++.dg/template/sfinae19.C (revision 0) +++ testsuite/g++.dg/template/sfinae19.C (revision 0) @@ -0,0 +1,44 @@ +// PR c++/44907 + +struct A { }; + +struct B +: public A { }; + +struct C +: public A { }; + +struct D +: public B, public C { }; + +template struct enable_if { typedef T type; }; +template struct enable_if { }; + +template + class mini_is_convertible + { + typedef char one; + typedef struct { char arr[2]; } two; + + template + static void test_aux(To1); + + template + static typename + enable_if<(sizeof(test_aux(From1()), 1) > 0), one>::type + test(int); + + template + static two test(...); + + public: + static const bool value = sizeof(test(0)) == 1; + }; + +template + const bool mini_is_convertible::value; + +int Test1[mini_is_convertible::value ? -1 : 1]; +int Test2[mini_is_convertible::value ? -1 : 1]; +int Test3[mini_is_convertible::value ? -1 : 1]; +int Test4[mini_is_convertible::value ? -1 : 1]; Index: cp/call.c =================================================================== --- cp/call.c (revision 162079) +++ cp/call.c (working copy) @@ -204,7 +204,7 @@ static void add_candidates (tree, tree, const VEC( 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, tre 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, t 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))