aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorPaolo Carlini <paolo.carlini@oracle.com>2010-07-12 19:59:31 +0000
committerPaolo Carlini <paolo@gcc.gnu.org>2010-07-12 19:59:31 +0000
commit248ce2f8d14c044c9c540a02f112c521a2e616b0 (patch)
tree549fbd7f45b4c2063e6078f170a0a31b1abddd5a /gcc
parentac9b0eeae0cd0d51908039aae35d1dff6a1486aa (diff)
downloadgcc-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/ChangeLog7
-rw-r--r--gcc/cp/call.c8
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/g++.dg/template/sfinae19.C44
-rw-r--r--gcc/testsuite/g++.dg/template/sfinae20.C45
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, "");