+2010-04-27 Jason Merrill <jason@redhat.com>
+
+ PR c++/41468
+ * class.c (convert_to_base): Add complain parameter. Pass
+ ba_quiet to lookup_base if we don't want errors.
+ (build_vfield_ref): Pass complain to convert_to_base.
+ * call.c (convert_like_real): Likewise.
+ (initialize_reference): Likewise.
+ (perform_direct_initialization_if_possible): Pass complain to
+ convert_like_real.
+ * cp-tree.h: Adjust.
+
2010-04-27 Fabien ChĂȘne <fabien.chene@gmail.com>
Jason Merrill <jason@redhat.com>
/* Build an expression for `*((base*) &expr)'. */
expr = cp_build_unary_op (ADDR_EXPR, expr, 0, complain);
expr = convert_to_base (expr, build_pointer_type (totype),
- !c_cast_p, /*nonnull=*/true);
+ !c_cast_p, /*nonnull=*/true, complain);
expr = cp_build_indirect_ref (expr, RO_IMPLICIT_CONVERSION, complain);
return expr;
}
case ck_ptr:
if (convs->base_p)
expr = convert_to_base (expr, totype, !c_cast_p,
- /*nonnull=*/false);
+ /*nonnull=*/false, complain);
return build_nop (totype, expr);
case ck_pmem:
expr = convert_like_real (conv, expr, NULL_TREE, 0, 0,
/*issue_conversion_warnings=*/false,
c_cast_p,
- tf_warning_or_error);
+ complain);
/* Free all the conversions we allocated. */
obstack_free (&conversion_obstack, p);
expr = convert_to_base (expr,
build_pointer_type (base_conv_type),
/*check_access=*/true,
- /*nonnull=*/true);
+ /*nonnull=*/true, complain);
expr = build2 (COMPOUND_EXPR, TREE_TYPE (expr), init, expr);
}
else
assumed to be non-NULL. */
tree
-convert_to_base (tree object, tree type, bool check_access, bool nonnull)
+convert_to_base (tree object, tree type, bool check_access, bool nonnull,
+ tsubst_flags_t complain)
{
tree binfo;
tree object_type;
+ base_access access;
if (TYPE_PTR_P (TREE_TYPE (object)))
{
else
object_type = TREE_TYPE (object);
+ access = check_access ? ba_check : ba_unique;
+ if (!(complain & tf_error))
+ access |= ba_quiet;
binfo = lookup_base (object_type, type,
- check_access ? ba_check : ba_unique,
+ access,
NULL);
if (!binfo || binfo == error_mark_node)
return error_mark_node;
/* First, convert to the requested type. */
if (!same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (datum), type))
datum = convert_to_base (datum, type, /*check_access=*/false,
- /*nonnull=*/true);
+ /*nonnull=*/true, tf_warning_or_error);
/* Second, the requested type may not be the owner of its own vptr.
If not, convert to the base class that owns it. We cannot use
extern tree build_vfield_ref (tree, tree);
extern tree build_base_path (enum tree_code, tree,
tree, int);
-extern tree convert_to_base (tree, tree, bool, bool);
+extern tree convert_to_base (tree, tree, bool, bool,
+ tsubst_flags_t);
extern tree convert_to_base_statically (tree, tree);
extern tree build_vtbl_ref (tree, tree);
extern tree build_vfn_ref (tree, tree);
+2010-04-27 Jason Merrill <jason@redhat.com>
+
+ PR c++/41468
+ * g++.dg/template/sfinae17.C: New.
+
2010-04-27 Fabien ChĂȘne <fabien.chene@gmail.com>
* g++.dg/init/pr42844.C: New.
--- /dev/null
+// The conversion from D* to B* is ambiguous, but that should not produce
+// an error, it should remove the first f overload by SFINAE.
+
+#define static_assert(TEST,STR) \
+ do { int ar[(TEST)?1:-1]; } while (0);
+
+struct B {};
+
+struct B1 : B {};
+struct B2 : B {};
+
+struct D : B1, B2 {};
+
+template <class T> T create();
+
+typedef char one[1];
+typedef char two[2];
+
+template <class T>
+ one &f(char (*)[sizeof static_cast<T>(create<D *>())]);
+template <class T>
+ two &f(...);
+
+int main()
+{
+ static_assert(sizeof f<int>(0) == sizeof(two), "");
+ static_assert(sizeof f<B *>(0) == sizeof(two), "");
+}