#include "coretypes.h"
#include "tm.h"
#include "tree.h"
+#include "stor-layout.h"
#include "flags.h"
#include "cp-tree.h"
#include "intl.h"
#include "convert.h"
#include "decl.h"
#include "target.h"
+#include "wide-int.h"
static tree cp_convert_to_pointer (tree, tree, tsubst_flags_t);
static tree convert_to_pointer_force (tree, tree, tsubst_flags_t);
static tree build_type_conversion (tree, tree);
static tree build_up_reference (tree, tree, int, tree, tsubst_flags_t);
-static void warn_ref_binding (location_t, tree, tree, tree);
+static void diagnose_ref_binding (location_t, tree, tree, tree);
/* Change of width--truncation and extension of integers or reals--
is represented with NOP_EXPR. Proper functioning of many things
}
/* Handle anachronistic conversions from (::*)() to cv void* or (*)(). */
- if (TREE_CODE (type) == POINTER_TYPE
+ if (TYPE_PTR_P (type)
&& (TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE
|| VOID_TYPE_P (TREE_TYPE (type))))
{
if (TYPE_PTRMEMFUNC_P (intype)
|| TREE_CODE (intype) == METHOD_TYPE)
return convert_member_func_to_ptr (type, expr, complain);
- if (TREE_CODE (TREE_TYPE (expr)) == POINTER_TYPE)
+ if (TYPE_PTR_P (TREE_TYPE (expr)))
return build_nop (type, expr);
intype = TREE_TYPE (expr);
}
intype = TYPE_MAIN_VARIANT (intype);
if (TYPE_MAIN_VARIANT (type) != intype
- && TREE_CODE (type) == POINTER_TYPE
+ && TYPE_PTR_P (type)
&& TREE_CODE (TREE_TYPE (type)) == RECORD_TYPE
&& MAYBE_CLASS_TYPE_P (TREE_TYPE (type))
&& MAYBE_CLASS_TYPE_P (TREE_TYPE (intype))
if (null_ptr_cst_p (expr))
{
- if (complain & tf_warning)
- maybe_warn_zero_as_null_pointer_constant (expr, loc);
-
if (TYPE_PTRMEMFUNC_P (type))
return build_ptrmemfunc (TYPE_PTRMEMFUNC_FN_TYPE (type), expr, 0,
/*c_cast_p=*/false, complain);
+ if (complain & tf_warning)
+ maybe_warn_zero_as_null_pointer_constant (expr, loc);
+
/* A NULL pointer-to-data-member is represented by -1, not by
zero. */
tree val = (TYPE_PTRDATAMEM_P (type)
non-volatile const type. */
static void
-warn_ref_binding (location_t loc, tree reftype, tree intype, tree decl)
+diagnose_ref_binding (location_t loc, tree reftype, tree intype, tree decl)
{
tree ttl = TREE_TYPE (reftype);
intype = TYPE_MAIN_VARIANT (intype);
- can_convert_intype_to_type = can_convert (type, intype, complain);
+ can_convert_intype_to_type = can_convert_standard (type, intype, complain);
if (!can_convert_intype_to_type
&& (convtype & CONV_IMPLICIT) && MAYBE_CLASS_TYPE_P (intype)
}
}
- if (((convtype & CONV_STATIC) && can_convert (intype, type, complain))
+ if (((convtype & CONV_STATIC)
+ && can_convert_standard (intype, type, complain))
|| ((convtype & CONV_IMPLICIT) && can_convert_intype_to_type))
{
{
tree ttl = TREE_TYPE (reftype);
tree ttr = lvalue_type (expr);
- if ((complain & tf_warning)
+ if ((complain & tf_error)
&& ! real_lvalue_p (expr))
- warn_ref_binding (loc, reftype, intype, decl);
+ diagnose_ref_binding (loc, reftype, intype, decl);
if (! (convtype & CONV_CONST)
&& !at_least_as_qualified_p (ttl, ttr))
/* B* bp; A& ar = (A&)bp; is valid, but it's probably not what they
meant. */
if ((complain & tf_warning)
- && TREE_CODE (intype) == POINTER_TYPE
+ && TYPE_PTR_P (intype)
&& (comptypes (TREE_TYPE (intype), type,
COMPARE_BASE | COMPARE_DERIVED)))
warning_at (loc, 0, "casting %qT to %qT does not dereference pointer",
ICR_CONVERTING, 0, 0, complain);
if (rval == NULL_TREE || rval == error_mark_node)
return rval;
- if (complain & tf_warning)
- warn_ref_binding (loc, reftype, intype, decl);
+ if (complain & tf_error)
+ diagnose_ref_binding (loc, reftype, intype, decl);
rval = build_up_reference (reftype, rval, flags, decl, complain);
}
{
gcc_assert (!TREE_OVERFLOW (orig));
/* Ensure constant sharing. */
- expr = build_int_cst_wide (TREE_TYPE (expr),
- TREE_INT_CST_LOW (expr),
- TREE_INT_CST_HIGH (expr));
+ expr = wide_int_to_tree (TREE_TYPE (expr), expr);
}
return expr;
}
result = cp_convert (type, expr, complain);
if ((complain & tf_warning)
- && c_inhibit_evaluation_warnings == 0
- && !TREE_OVERFLOW_P (expr)
- && result != error_mark_node)
- warnings_for_convert_and_check (type, expr, result);
+ && c_inhibit_evaluation_warnings == 0)
+ {
+ tree folded = maybe_constant_value (expr);
+ tree stripped = folded;
+ tree folded_result = cp_convert (type, folded, complain);
+
+ /* maybe_constant_value wraps an INTEGER_CST with TREE_OVERFLOW in a
+ NOP_EXPR so that it isn't TREE_CONSTANT anymore. */
+ STRIP_NOPS (stripped);
+
+ if (!TREE_OVERFLOW_P (stripped)
+ && folded_result != error_mark_node)
+ warnings_for_convert_and_check (type, folded, folded_result);
+ }
return result;
}
if (((INTEGRAL_OR_ENUMERATION_TYPE_P (intype)
|| TREE_CODE (intype) == REAL_TYPE)
&& ! (convtype & CONV_STATIC))
- || TREE_CODE (intype) == POINTER_TYPE)
+ || TYPE_PTR_P (intype))
{
if (complain & tf_error)
permerror (loc, "conversion from %q#T to %q#T", intype, type);
}
if (code == BOOLEAN_TYPE)
{
- if (TREE_CODE (intype) == VOID_TYPE)
+ if (VOID_TYPE_P (intype))
{
if (complain & tf_error)
error_at (loc,
exprv = TREE_OPERAND (exprv, 1);
if (DECL_P (exprv)
|| handled_component_p (exprv)
- || TREE_CODE (exprv) == INDIRECT_REF)
+ || INDIRECT_REF_P (exprv))
/* Expr is not being 'used' here, otherwise we whould have
called mark_{rl}value_use use here, which would have in turn
called mark_exp_read. Rather, we call mark_exp_read directly
complain));
/* From typeck.c convert_for_assignment */
- if (((TREE_CODE (TREE_TYPE (e)) == POINTER_TYPE && TREE_CODE (e) == ADDR_EXPR
- && TREE_CODE (TREE_TYPE (e)) == POINTER_TYPE
+ if (((TYPE_PTR_P (TREE_TYPE (e)) && TREE_CODE (e) == ADDR_EXPR
&& TREE_CODE (TREE_TYPE (TREE_TYPE (e))) == METHOD_TYPE)
|| integer_zerop (e)
|| TYPE_PTRMEMFUNC_P (TREE_TYPE (e)))
if (DECL_NONCONVERTING_P (cand))
continue;
- if (TREE_CODE (cand) == TEMPLATE_DECL)
- {
- if (complain)
- {
- error ("ambiguous default type conversion from %qT",
- basetype);
- error (" candidate conversions include %qD", cand);
- }
- return error_mark_node;
- }
-
candidate = non_reference (TREE_TYPE (TREE_TYPE (cand)));
switch (TREE_CODE (candidate))
break;
default:
+ /* A wildcard could be instantiated to match any desired
+ type, but we can't deduce the template argument. */
+ if (WILDCARD_TYPE_P (candidate))
+ win = true;
break;
}
if (win)
{
- if (winner)
+ if (TREE_CODE (cand) == TEMPLATE_DECL)
{
if (complain)
+ error ("default type conversion can't deduce template"
+ " argument for %qD", cand);
+ return error_mark_node;
+ }
+
+ if (winner)
+ {
+ tree winner_type
+ = non_reference (TREE_TYPE (TREE_TYPE (winner)));
+
+ if (!same_type_ignoring_top_level_qualifiers_p (winner_type,
+ candidate))
{
- error ("ambiguous default type conversion from %qT",
- basetype);
- error (" candidate conversions include %qD and %qD",
- winner, cand);
+ if (complain)
+ {
+ error ("ambiguous default type conversion from %qT",
+ basetype);
+ error (" candidate conversions include %qD and %qD",
+ winner, cand);
+ }
+ return error_mark_node;
}
- return error_mark_node;
}
- else
- winner = cand;
+
+ winner = cand;
}
}