===================================================================
@@ -13,7 +13,7 @@ template<int> void foo()
__is_abstract(int)(); // { dg-error "'__is_abstract\\(int\\)' cannot be used" }
__is_base_of(int, float)(); // { dg-error "'__is_base_of\\(int, float\\)' cannot be used" }
__is_class(int)(); // { dg-error "'__is_class\\(int\\)' cannot be used" }
- __is_convertible_to(int, float)(); // { dg-message "unimplemented" }
+ __is_convertible_to(int, float)(); // { dg-error "'__is_convertible_to\\(int, float\\)' cannot be used" }
__is_empty(int)(); // { dg-error "'__is_empty\\(int\\)' cannot be used" }
__is_enum(int)(); // { dg-error "'__is_enum\\(int\\)' cannot be used" }
__is_pod(int)(); // { dg-error "'__is_pod\\(int\\)' cannot be used" }
===================================================================
@@ -0,0 +1,142 @@
+// { dg-do "run" }
+#include <cassert>
+
+class A
+{ };
+
+class B
+: public A { };
+
+class C
+: public A { };
+
+enum E
+{
+ e0
+};
+
+class D
+: public B, public C { };
+
+class F
+: private A { };
+
+class G
+: public virtual A { };
+
+struct X
+{
+ operator int();
+};
+
+struct Y
+{
+ operator X();
+};
+
+class Z
+{
+ operator int();
+};
+
+template<typename T, typename U>
+ bool
+ f()
+ { return __is_convertible_to(T, U); }
+
+template<typename T, typename U>
+ class My
+ {
+ public:
+ bool
+ f()
+ { return !!__is_convertible_to(T, U); }
+ };
+
+template<typename T, typename U>
+ class My2
+ {
+ public:
+ static const bool trait = __is_convertible_to(T, U);
+ };
+
+template<typename T, typename U>
+ const bool My2<T, U>::trait;
+
+template<typename T, typename U, bool b = __is_convertible_to(T, U)>
+ struct My3_help
+ { static const bool trait = b; };
+
+template<typename T, typename U, bool b>
+ const bool My3_help<T, U, b>::trait;
+
+template<typename T, typename U>
+ class My3
+ {
+ public:
+ bool
+ f()
+ { return My3_help<T, U>::trait; }
+ };
+
+#define PTEST(T, U) (__is_convertible_to(T, U) && f<T, U>() \
+ && My<T, U>().f() && My2<T, U>::trait && My3<T, U>().f())
+
+#define NTEST(T, U) (!__is_convertible_to(T, U) && !f<T, U>() \
+ && !My<T, U>().f() && !My2<T, U>::trait \
+ && !My3<T, U>().f())
+
+int main()
+{
+ assert (NTEST (int, void));
+ assert (NTEST (void, int));
+ assert (PTEST (void, void));
+ assert (PTEST (int, float));
+ assert (PTEST (float, int));
+ assert (PTEST (int*, const int*));
+ assert (NTEST (const int*, int*));
+ assert (PTEST (int*, void*));
+ assert (NTEST (void*, int*));
+ assert (NTEST (int*, float*));
+ assert (PTEST (int&, const int&));
+ assert (NTEST (const int&, int&));
+ assert (PTEST (int&, int));
+ assert (NTEST (int, int&));
+ assert (PTEST (const int, const int&));
+ assert (NTEST (volatile int, volatile int&));
+ assert (NTEST (const volatile int, const volatile int&));
+ assert (NTEST (int (int), int (int)));
+ assert (NTEST (int[], int[]));
+ assert (PTEST (int[], int*));
+ assert (PTEST (int (int), int (*) (int)));
+ assert (NTEST (int (int), int (&) (int)));
+ assert (PTEST (A, A));
+ assert (NTEST (int, A));
+ assert (NTEST (A, int));
+ assert (PTEST (B, A));
+ assert (NTEST (A, B));
+ assert (PTEST (B*, A*));
+ assert (NTEST (A*, B*));
+ assert (PTEST (B&, A&));
+ assert (NTEST (A&, B&));
+ assert (PTEST (int (A::*), int (B::*)));
+ assert (NTEST (int (B::*), int (A::*)));
+ assert (PTEST (int (A::*) (int), int (B::*) (int)));
+ assert (NTEST (int (B::*) (int), int (A::*) (int)));
+ assert (PTEST (E, int));
+ assert (NTEST (int, E));
+ assert (NTEST (D, A));
+ assert (NTEST (F, A));
+ assert (NTEST (F*, A*));
+ assert (NTEST (F&, A&));
+ assert (NTEST (int (A::*), int (F::*)));
+ assert (NTEST (int (A::*) (int), int (F::*) (int)));
+ assert (NTEST (int (A::*), int (G::*)));
+ assert (NTEST (int (A::*) (int), int (G::*) (int)));
+ assert (PTEST (X, int));
+ assert (NTEST (Y, int));
+ assert (PTEST (Y, X));
+ assert (NTEST (Z, int));
+
+ return 0;
+}
===================================================================
@@ -1,6 +1,6 @@
/* Build expressions with type checking for C++ compiler.
Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+ 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
Free Software Foundation, Inc.
Hacked by Michael Tiemann (tiemann@cygnus.com)
@@ -53,7 +53,7 @@ static int comp_ptr_ttypes_real (tree, tree, int);
static bool comp_except_types (tree, tree, bool);
static bool comp_array_types (const_tree, const_tree, bool);
static tree pointer_diff (tree, tree, tree);
-static tree get_delta_difference (tree, tree, bool, bool);
+static tree get_delta_difference (tree, tree, bool, bool, tsubst_flags_t);
static void casts_away_constness_r (tree *, tree *);
static bool casts_away_constness (tree, tree);
static void maybe_warn_about_returning_address_of_local (tree);
@@ -5254,7 +5254,8 @@ cp_build_unary_op (enum tree_code code, tree xarg,
{
build_ptrmemfunc_type (argtype);
val = build_ptrmemfunc (argtype, val, 0,
- /*c_cast_p=*/false);
+ /*c_cast_p=*/false,
+ tf_warning_or_error);
}
return val;
@@ -5669,7 +5670,7 @@ check_for_casting_away_constness (tree src_type, t
tree
convert_ptrmem (tree type, tree expr, bool allow_inverse_p,
- bool c_cast_p)
+ bool c_cast_p, tsubst_flags_t complain)
{
if (TYPE_PTRMEM_P (type))
{
@@ -5680,7 +5681,10 @@ convert_ptrmem (tree type, tree expr, bool allow_i
delta = get_delta_difference (TYPE_PTRMEM_CLASS_TYPE (TREE_TYPE (expr)),
TYPE_PTRMEM_CLASS_TYPE (type),
allow_inverse_p,
- c_cast_p);
+ c_cast_p, complain);
+ if (delta == error_mark_node)
+ return error_mark_node;
+
if (!integer_zerop (delta))
{
tree cond, op1, op2;
@@ -5704,7 +5708,7 @@ convert_ptrmem (tree type, tree expr, bool allow_i
}
else
return build_ptrmemfunc (TYPE_PTRMEMFUNC_FN_TYPE (type), expr,
- allow_inverse_p, c_cast_p);
+ allow_inverse_p, c_cast_p, complain);
}
/* If EXPR is an INTEGER_CST and ORIG is an arithmetic constant, return
@@ -5940,7 +5944,7 @@ build_static_cast_1 (tree type, tree expr, bool c_
if (!c_cast_p)
check_for_casting_away_constness (intype, type, STATIC_CAST_EXPR);
return convert_ptrmem (type, expr, /*allow_inverse_p=*/1,
- c_cast_p);
+ c_cast_p, tf_warning_or_error);
}
}
@@ -6855,20 +6859,30 @@ build_x_modify_expr (tree lhs, enum tree_code modi
/* Helper function for get_delta_difference which assumes FROM is a base
class of TO. Returns a delta for the conversion of pointer-to-member
- of FROM to pointer-to-member of TO. If the conversion is invalid,
+ of FROM to pointer-to-member of TO. If the conversion is invalid and
+ tf_error is not set in COMPLAIN returns error_mark_node, otherwise
returns zero. If FROM is not a base class of TO, returns NULL_TREE.
- If C_CAST_P is true, this conversion is taking place as part of a C-style
- cast. */
+ If C_CAST_P is true, this conversion is taking place as part of a
+ C-style cast. */
static tree
-get_delta_difference_1 (tree from, tree to, bool c_cast_p)
+get_delta_difference_1 (tree from, tree to, bool c_cast_p,
+ tsubst_flags_t complain)
{
tree binfo;
base_kind kind;
- binfo = lookup_base (to, from, c_cast_p ? ba_unique : ba_check, &kind);
+ if (complain & tf_error)
+ binfo = lookup_base (to, from, c_cast_p ? ba_unique : ba_check, &kind);
+ else
+ binfo = lookup_base (to, from,
+ ba_quiet | (c_cast_p ? ba_unique : ba_check), &kind);
+
if (kind == bk_inaccessible || kind == bk_ambig)
{
+ if (!(complain & tf_error))
+ return error_mark_node;
+
error (" in pointer to member function conversion");
return size_zero_node;
}
@@ -6880,22 +6894,26 @@ static tree
/* FROM is a virtual base class of TO. Issue an error or warning
depending on whether or not this is a reinterpret cast. */
{
+ if (!(complain & tf_error))
+ return error_mark_node;
+
error ("pointer to member conversion via virtual base %qT",
BINFO_TYPE (binfo_from_vbase (binfo)));
return size_zero_node;
}
}
- else
- return NULL_TREE;
+ else
+ return NULL_TREE;
}
/* Get difference in deltas for different pointer to member function
- types. Returns an integer constant of type PTRDIFF_TYPE_NODE. If
- the conversion is invalid, the constant is zero. If
- ALLOW_INVERSE_P is true, then allow reverse conversions as well.
- If C_CAST_P is true this conversion is taking place as part of a
- C-style cast.
+ types. If the conversion is invalid and tf_error is not set in
+ COMPLAIN, returns error_mark_node, otherwise returns an integer
+ constant of type PTRDIFF_TYPE_NODE and its value is zero if the
+ conversion is invalid. If ALLOW_INVERSE_P is true, then allow reverse
+ conversions as well. If C_CAST_P is true this conversion is taking
+ place as part of a C-style cast.
Note that the naming of FROM and TO is kind of backwards; the return
value is what we add to a TO in order to get a FROM. They are named
@@ -6905,7 +6923,7 @@ static tree
static tree
get_delta_difference (tree from, tree to,
bool allow_inverse_p,
- bool c_cast_p)
+ bool c_cast_p, tsubst_flags_t complain)
{
tree result;
@@ -6913,25 +6931,37 @@ get_delta_difference (tree from, tree to,
/* Pointer to member of incomplete class is permitted*/
result = size_zero_node;
else
- result = get_delta_difference_1 (from, to, c_cast_p);
+ result = get_delta_difference_1 (from, to, c_cast_p, complain);
+ if (result == error_mark_node)
+ return error_mark_node;
+
if (!result)
{
if (!allow_inverse_p)
{
+ if (!(complain & tf_error))
+ return error_mark_node;
+
error_not_base_type (from, to);
error (" in pointer to member conversion");
- result = size_zero_node;
+ result = size_zero_node;
}
else
{
- result = get_delta_difference_1 (to, from, c_cast_p);
+ result = get_delta_difference_1 (to, from, c_cast_p, complain);
+ if (result == error_mark_node)
+ return error_mark_node;
+
if (result)
result = size_diffop_loc (input_location,
- size_zero_node, result);
+ size_zero_node, result);
else
{
+ if (!(complain & tf_error))
+ return error_mark_node;
+
error_not_base_type (from, to);
error (" in pointer to member conversion");
result = size_zero_node;
@@ -6990,7 +7020,8 @@ build_ptrmemfunc1 (tree type, tree delta, tree pfn
Return error_mark_node, if something goes wrong. */
tree
-build_ptrmemfunc (tree type, tree pfn, int force, bool c_cast_p)
+build_ptrmemfunc (tree type, tree pfn, int force, bool c_cast_p,
+ tsubst_flags_t complain)
{
tree fn;
tree pfn_type;
@@ -7017,7 +7048,9 @@ tree
n = get_delta_difference (TYPE_PTRMEMFUNC_OBJECT_TYPE (pfn_type),
TYPE_PTRMEMFUNC_OBJECT_TYPE (to_type),
force,
- c_cast_p);
+ c_cast_p, complain);
+ if (n == error_mark_node)
+ return error_mark_node;
/* We don't have to do any conversion to convert a
pointer-to-member to its own type. But, we don't want to
@@ -7100,7 +7133,7 @@ expand_ptrmemfunc_cst (tree cst, tree *delta, tree
/* First, calculate the adjustment to the function's class. */
*delta = get_delta_difference (fn_class, ptr_class, /*force=*/0,
- /*c_cast_p=*/0);
+ /*c_cast_p=*/0, tf_warning_or_error);
if (!DECL_VIRTUAL_P (fn))
*pfn = convert (TYPE_PTRMEMFUNC_FN_TYPE (type), build_addr_func (fn));
===================================================================
@@ -5039,8 +5039,7 @@ trait_expr_value (cp_trait_kind kind, tree type1,
return (NON_UNION_CLASS_TYPE_P (type1));
case CPTK_IS_CONVERTIBLE_TO:
- /* TODO */
- return false;
+ return trait_is_convertible_to (type1, type2);
case CPTK_IS_EMPTY:
return (NON_UNION_CLASS_TYPE_P (type1) && CLASSTYPE_EMPTY_P (type1));
@@ -5113,12 +5112,6 @@ finish_trait_expr (cp_trait_kind kind, tree type1,
|| kind == CPTK_IS_TRIVIAL
|| kind == CPTK_IS_UNION);
- if (kind == CPTK_IS_CONVERTIBLE_TO)
- {
- sorry ("__is_convertible_to");
- return error_mark_node;
- }
-
if (type1 == error_mark_node
|| ((kind == CPTK_IS_BASE_OF || kind == CPTK_IS_CONVERTIBLE_TO)
&& type2 == error_mark_node))
@@ -5171,12 +5164,24 @@ finish_trait_expr (cp_trait_kind kind, tree type1,
}
break;
+ case CPTK_IS_CONVERTIBLE_TO:
+ if (!check_trait_type (type1))
+ {
+ error ("incomplete type %qT not allowed", type1);
+ return error_mark_node;
+ }
+ if (!check_trait_type (type2))
+ {
+ error ("incomplete type %qT not allowed", type2);
+ return error_mark_node;
+ }
+ break;
+
case CPTK_IS_CLASS:
case CPTK_IS_ENUM:
case CPTK_IS_UNION:
break;
- case CPTK_IS_CONVERTIBLE_TO:
default:
gcc_unreachable ();
}
===================================================================
@@ -139,13 +139,13 @@ static tree build_java_interface_fn_ref (tree, tre
#define convert_like(CONV, EXPR, COMPLAIN) \
convert_like_real ((CONV), (EXPR), NULL_TREE, 0, 0, \
/*issue_conversion_warnings=*/true, \
- /*c_cast_p=*/false, (COMPLAIN))
+ /*c_cast_p=*/false, (COMPLAIN), LOOKUP_NORMAL)
#define convert_like_with_context(CONV, EXPR, FN, ARGNO, COMPLAIN ) \
convert_like_real ((CONV), (EXPR), (FN), (ARGNO), 0, \
/*issue_conversion_warnings=*/true, \
- /*c_cast_p=*/false, (COMPLAIN))
+ /*c_cast_p=*/false, (COMPLAIN), LOOKUP_NORMAL)
static tree convert_like_real (conversion *, tree, tree, int, int, bool,
- bool, tsubst_flags_t);
+ bool, tsubst_flags_t, int);
static void op_error (enum tree_code, enum tree_code, tree, tree,
tree, bool);
static VEC(tree,gc) *resolve_args (VEC(tree,gc) *);
@@ -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;
@@ -4911,11 +4911,10 @@ conversion_null_warnings (tree totype, tree expr,
static tree
convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
int inner, bool issue_conversion_warnings,
- bool c_cast_p, tsubst_flags_t complain)
+ bool c_cast_p, tsubst_flags_t complain, int flags)
{
tree totype = convs->type;
diagnostic_t diag_kind;
- int flags;
if (convs->bad_p
&& convs->kind != ck_user
@@ -4941,14 +4940,14 @@ convert_like_real (conversion *convs, tree expr, t
expr = convert_like_real (t, expr, fn, argnum, 1,
/*issue_conversion_warnings=*/false,
/*c_cast_p=*/false,
- complain);
+ complain, flags);
break;
}
else if (t->kind == ck_ambig)
return convert_like_real (t, expr, fn, argnum, 1,
/*issue_conversion_warnings=*/false,
/*c_cast_p=*/false,
- complain);
+ complain, flags);
else if (t->kind == ck_identity)
break;
}
@@ -4997,7 +4996,7 @@ convert_like_real (conversion *convs, tree expr, t
for (i = 0; i < cand->num_convs; ++i)
cand->convs[i]->user_conv_p = true;
- expr = build_over_call (cand, LOOKUP_NORMAL, complain);
+ expr = build_over_call (cand, flags, complain);
/* If this is a constructor or a function returning an aggr type,
we need to build up a TARGET_EXPR. */
@@ -5064,7 +5063,7 @@ convert_like_real (conversion *convs, tree expr, t
FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (expr), ix, val)
{
tree sub = convert_like_real (convs->u.list[ix], val, fn, argnum,
- 1, false, false, complain);
+ 1, false, false, complain, flags);
if (sub == error_mark_node)
return sub;
check_narrowing (TREE_TYPE (sub), val);
@@ -5099,7 +5098,8 @@ convert_like_real (conversion *convs, tree expr, t
convs->kind == ck_ref_bind ? -1 : 1,
convs->kind == ck_ref_bind ? issue_conversion_warnings : false,
c_cast_p,
- complain);
+ complain,
+ LOOKUP_NORMAL);
if (expr == error_mark_node)
return error_mark_node;
@@ -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))
@@ -5246,7 +5246,7 @@ convert_like_real (conversion *convs, tree expr, t
case ck_pmem:
return convert_ptrmem (totype, expr, /*allow_inverse_p=*/false,
- c_cast_p);
+ c_cast_p, complain);
default:
break;
@@ -7597,7 +7597,8 @@ can_convert_arg_bad (tree to, tree from, tree arg,
doing a bad conversion, convert_like will complain. */
tree
-perform_implicit_conversion_flags (tree type, tree expr, tsubst_flags_t complain, int flags)
+perform_implicit_conversion_flags (tree type, tree expr,
+ tsubst_flags_t complain, int flags)
{
conversion *conv;
void *p;
@@ -7698,7 +7699,8 @@ perform_direct_initialization_if_possible (tree ty
expr = convert_like_real (conv, expr, NULL_TREE, 0, 0,
/*issue_conversion_warnings=*/false,
c_cast_p,
- complain);
+ complain,
+ LOOKUP_NORMAL);
/* Free all the conversions we allocated. */
obstack_free (&conversion_obstack, p);
@@ -7706,6 +7708,43 @@ perform_direct_initialization_if_possible (tree ty
return expr;
}
+/* Called from trait_expr_value to evaluate __is_convertible_to. */
+
+bool
+trait_is_convertible_to (tree from, tree to)
+{
+ if (error_operand_p (from) || error_operand_p (to))
+ return false;
+
+ if (VOID_TYPE_P (from))
+ return VOID_TYPE_P (to) ? true : false;
+ else
+ {
+ tree expr = force_target_expr (from, build_dummy_object (from));
+ conversion *conv;
+ void *p;
+
+ /* Get the high-water mark for the CONVERSION_OBSTACK. */
+ p = conversion_obstack_alloc (0);
+
+ conv = implicit_conversion (to, TREE_TYPE (expr), expr,
+ /*c_cast_p=*/false,
+ LOOKUP_SPECULATIVE);
+ if (!conv)
+ expr = error_mark_node;
+ else
+ expr = convert_like_real (conv, expr, NULL_TREE, 0, 0,
+ /*issue_conversion_warnings=*/true,
+ /*c_cast_p=*/false, tf_none,
+ LOOKUP_SPECULATIVE);
+
+ /* Free all the conversions we allocated. */
+ obstack_free (&conversion_obstack, p);
+
+ return expr == error_mark_node ? false : true;
+ }
+}
+
/* DECL is a VAR_DECL whose type is a REFERENCE_TYPE. The reference
is being bound to a temporary. Create and return a new VAR_DECL
with the indicated TYPE; this variable will store the value to
@@ -7909,7 +7948,8 @@ initialize_reference (tree type, tree expr, tree d
/*inner=*/-1,
/*issue_conversion_warnings=*/true,
/*c_cast_p=*/false,
- tf_warning_or_error);
+ tf_warning_or_error,
+ LOOKUP_NORMAL);
if (error_operand_p (expr))
expr = error_mark_node;
else
===================================================================
@@ -176,7 +176,7 @@ cp_convert_to_pointer (tree type, tree expr)
else if ((TYPE_PTRMEM_P (type) && TYPE_PTRMEM_P (intype))
|| (TYPE_PTRMEMFUNC_P (type) && TYPE_PTRMEMFUNC_P (intype)))
return convert_ptrmem (type, expr, /*allow_inverse_p=*/false,
- /*c_cast_p=*/false);
+ /*c_cast_p=*/false, tf_warning_or_error);
else if (TYPE_PTRMEMFUNC_P (intype))
{
if (!warn_pmf2ptr)
@@ -200,7 +200,7 @@ cp_convert_to_pointer (tree type, tree expr)
{
if (TYPE_PTRMEMFUNC_P (type))
return build_ptrmemfunc (TYPE_PTRMEMFUNC_FN_TYPE (type), expr, 0,
- /*c_cast_p=*/false);
+ /*c_cast_p=*/false, tf_warning_or_error);
if (TYPE_PTRMEM_P (type))
{
@@ -1376,7 +1376,7 @@ convert_force (tree type, tree expr, int convtype)
&& TYPE_PTRMEMFUNC_P (type))
/* compatible pointer to member functions. */
return build_ptrmemfunc (TYPE_PTRMEMFUNC_FN_TYPE (type), e, 1,
- /*c_cast_p=*/1);
+ /*c_cast_p=*/1, tf_warning_or_error);
return ocp_convert (type, e, CONV_C_CAST|convtype, LOOKUP_NORMAL);
}
===================================================================
@@ -4629,6 +4629,7 @@ extern tree perform_implicit_conversion (tree, tr
extern tree perform_implicit_conversion_flags (tree, tree, tsubst_flags_t, int);
extern tree perform_direct_initialization_if_possible (tree, tree, bool,
tsubst_flags_t);
+extern bool trait_is_convertible_to (tree, tree);
extern tree in_charge_arg_for_name (tree);
extern tree build_cxx_call (tree, int, tree *);
extern bool is_std_init_list (tree);
@@ -5483,7 +5484,8 @@ extern int comp_ptr_ttypes (tree, tree);
extern bool comp_ptr_ttypes_const (tree, tree);
extern bool error_type_p (const_tree);
extern int ptr_reasonably_similar (const_tree, const_tree);
-extern tree build_ptrmemfunc (tree, tree, int, bool);
+extern tree build_ptrmemfunc (tree, tree, int, bool,
+ tsubst_flags_t);
extern int cp_type_quals (const_tree);
extern int type_memfn_quals (const_tree);
extern tree apply_memfn_quals (tree, cp_cv_quals);
@@ -5512,7 +5514,8 @@ extern tree non_reference (tree);
extern tree lookup_anon_field (tree, tree);
extern bool invalid_nonstatic_memfn_p (const_tree, tsubst_flags_t);
extern tree convert_member_func_to_ptr (tree, tree);
-extern tree convert_ptrmem (tree, tree, bool, bool);
+extern tree convert_ptrmem (tree, tree, bool, bool,
+ tsubst_flags_t);
extern int lvalue_or_else (tree, enum lvalue_use,
tsubst_flags_t);
extern void check_template_keyword (tree);
===================================================================
@@ -306,31 +306,10 @@ namespace std
: public integral_constant<bool, __is_base_of(_Base, _Derived)>
{ };
- template<typename _From, typename _To,
- bool = (is_void<_From>::value || is_void<_To>::value
- || is_function<_To>::value || is_array<_To>::value)>
- struct __is_convertible_helper
- { static const bool __value = (is_void<_From>::value
- && is_void<_To>::value); };
-
- template<typename _From, typename _To>
- class __is_convertible_helper<_From, _To, false>
- : public __sfinae_types
- {
- static __one __test(_To);
- static __two __test(...);
-
- public:
- static const bool __value = sizeof(__test(declval<_From>())) == 1;
- };
-
/// is_convertible
- // XXX FIXME
- // The C++0x specifications require front-end support, see N2255.
template<typename _From, typename _To>
struct is_convertible
- : public integral_constant<bool,
- __is_convertible_helper<_From, _To>::__value>
+ : public integral_constant<bool, __is_convertible_to(_From, _To)>
{ };
/// is_explicitly_convertible
===================================================================
@@ -48,5 +48,5 @@ void test01()
// { dg-error "instantiated from here" "" { target *-*-* } 40 }
// { dg-error "instantiated from here" "" { target *-*-* } 42 }
-// { dg-error "invalid use of incomplete type" "" { target *-*-* } 639 }
-// { dg-error "declaration of" "" { target *-*-* } 603 }
+// { dg-error "invalid use of incomplete type" "" { target *-*-* } 618 }
+// { dg-error "declaration of" "" { target *-*-* } 582 }
===================================================================
@@ -48,5 +48,5 @@ void test01()
// { dg-error "instantiated from here" "" { target *-*-* } 40 }
// { dg-error "instantiated from here" "" { target *-*-* } 42 }
-// { dg-error "invalid use of incomplete type" "" { target *-*-* } 562 }
-// { dg-error "declaration of" "" { target *-*-* } 526 }
+// { dg-error "invalid use of incomplete type" "" { target *-*-* } 541 }
+// { dg-error "declaration of" "" { target *-*-* } 505 }
===================================================================
@@ -19,7 +19,7 @@
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
-// { dg-error "static assertion failed" "" { target *-*-* } 676 }
+// { dg-error "static assertion failed" "" { target *-*-* } 655 }
#include <utility>