[C++ PATCH]: warning on implicit float->int
Nathan Sidwell
nathan@codesourcery.com
Sun Mar 5 02:26:00 GMT 2000
Mark Mitchell wrote:
> Please check in the patch with those changes. And thanks!
I checked in the attached. There was a test case with the original
version of the patch, I forgot to copy it in the updated version
nathan
--
Dr Nathan Sidwell :: http://www.codesourcery.com :: CodeSourcery LLC
'But that's a lie.' - 'Yes it is. What's your point?'
nathan@codesourcery.com : http://www.cs.bris.ac.uk/~nathan/ : nathan@acm.org
2000-03-05 Nathan Sidwell <nathan@codesourcery.com>
* call.c (convert_like): Macrofy.
(convert_like_with_context): New macro.
(convert_like_real): Renamed from convert_like. Add calling
context parameters, for diagnostics. Add recursive flag. Call
dubious_conversion_warnings for outer conversion.
(build_user_type_conversion): Use convert_like_with_context.
(build_over_call): Likewise. Don't warn about dubious
conversions here. Adjust convert_default_arg calls.
(convert_default_arg): Add context parameters for diagnostics.
Pass throught to convert_like_with_context.
* cp-tree.h (convert_default_arg): Add context parameters.
(dubious_conversion_warnings): Prototype new function.
* typeck.c (convert_arguments): Adjust convert_default_arg call.
(dubious_conversion_warnings): New function, broken
out of convert_for_assignment.
(convert_for_assignment): Adjust.
Index: cp/call.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/call.c,v
retrieving revision 1.199
diff -c -3 -p -r1.199 call.c
*** call.c 2000/03/03 02:27:14 1.199
--- call.c 2000/03/05 09:49:33
*************** static int equal_functions PARAMS ((tree
*** 49,55 ****
static int joust PARAMS ((struct z_candidate *, struct z_candidate *, int));
static int compare_ics PARAMS ((tree, tree));
static tree build_over_call PARAMS ((struct z_candidate *, tree, int));
! static tree convert_like PARAMS ((tree, tree));
static void op_error PARAMS ((enum tree_code, enum tree_code, tree, tree,
tree, const char *));
static tree build_object_call PARAMS ((tree, tree));
--- 49,57 ----
static int joust PARAMS ((struct z_candidate *, struct z_candidate *, int));
static int compare_ics PARAMS ((tree, tree));
static tree build_over_call PARAMS ((struct z_candidate *, tree, int));
! #define convert_like(CONV, EXPR) convert_like_real (CONV, EXPR, NULL_TREE, 0, 0)
! #define convert_like_with_context(CONV, EXPR, FN, ARGNO) convert_like_real (CONV, EXPR, FN, ARGNO, 0)
! static tree convert_like_real PARAMS ((tree, tree, tree, int, int));
static void op_error PARAMS ((enum tree_code, enum tree_code, tree, tree,
tree, const char *));
static tree build_object_call PARAMS ((tree, tree));
*************** build_user_type_conversion (totype, expr
*** 2450,2456 ****
{
if (TREE_CODE (cand->second_conv) == AMBIG_CONV)
return error_mark_node;
! return convert_from_reference (convert_like (cand->second_conv, expr));
}
return NULL_TREE;
}
--- 2452,2460 ----
{
if (TREE_CODE (cand->second_conv) == AMBIG_CONV)
return error_mark_node;
! return convert_from_reference
! (convert_like_with_context
! (cand->second_conv, expr, cand->fn, 0));
}
return NULL_TREE;
}
*************** build_object_call (obj, args)
*** 2654,2660 ****
&& DECL_NAME (cand->fn) == ansi_opname [CALL_EXPR])
return build_over_call (cand, mem_args, LOOKUP_NORMAL);
! obj = convert_like (TREE_VEC_ELT (cand->convs, 0), obj);
/* FIXME */
return build_function_call (obj, args);
--- 2658,2665 ----
&& DECL_NAME (cand->fn) == ansi_opname [CALL_EXPR])
return build_over_call (cand, mem_args, LOOKUP_NORMAL);
! obj = convert_like_with_context
! (TREE_VEC_ELT (cand->convs, 0), obj, cand->fn, -1);
/* FIXME */
return build_function_call (obj, args);
*************** enforce_access (basetype_path, decl)
*** 3593,3603 ****
return 1;
}
! /* Perform the conversions in CONVS on the expression EXPR. */
static tree
! convert_like (convs, expr)
tree convs, expr;
{
if (ICS_BAD_FLAG (convs)
&& TREE_CODE (convs) != USER_CONV
--- 3598,3614 ----
return 1;
}
! /* Perform the conversions in CONVS on the expression EXPR.
! FN and ARGNUM are used for diagnostics. ARGNUM is zero based, -1
! indicates the `this' argument of a method. INNER is non-zero when
! being called to continue a conversion chain. */
static tree
! convert_like_real (convs, expr, fn, argnum, inner)
tree convs, expr;
+ tree fn;
+ int argnum;
+ int inner;
{
if (ICS_BAD_FLAG (convs)
&& TREE_CODE (convs) != USER_CONV
*************** convert_like (convs, expr)
*** 3609,3627 ****
{
if (TREE_CODE (t) == USER_CONV)
{
! expr = convert_like (t, expr);
break;
}
else if (TREE_CODE (t) == AMBIG_CONV)
! return convert_like (t, expr);
else if (TREE_CODE (t) == IDENTITY_CONV)
break;
}
return convert_for_initialization
(NULL_TREE, TREE_TYPE (convs), expr, LOOKUP_NORMAL,
! "conversion", NULL_TREE, 0);
}
!
switch (TREE_CODE (convs))
{
case USER_CONV:
--- 3620,3641 ----
{
if (TREE_CODE (t) == USER_CONV)
{
! expr = convert_like_real (t, expr, fn, argnum, 1);
break;
}
else if (TREE_CODE (t) == AMBIG_CONV)
! return convert_like_real (t, expr, fn, argnum, 1);
else if (TREE_CODE (t) == IDENTITY_CONV)
break;
}
return convert_for_initialization
(NULL_TREE, TREE_TYPE (convs), expr, LOOKUP_NORMAL,
! "conversion", fn, argnum);
}
!
! if (!inner)
! expr = dubious_conversion_warnings
! (TREE_TYPE (convs), expr, "argument", fn, argnum);
switch (TREE_CODE (convs))
{
case USER_CONV:
*************** convert_like (convs, expr)
*** 3665,3671 ****
break;
};
! expr = convert_like (TREE_OPERAND (convs, 0), expr);
if (expr == error_mark_node)
return error_mark_node;
--- 3679,3685 ----
break;
};
! expr = convert_like_real (TREE_OPERAND (convs, 0), expr, fn, argnum, 1);
if (expr == error_mark_node)
return error_mark_node;
*************** convert_type_from_ellipsis (type)
*** 3840,3849 ****
conversions. Return the converted value. */
tree
! convert_default_arg (type, arg, fn)
tree type;
tree arg;
tree fn;
{
if (fn && DECL_TEMPLATE_INFO (fn))
arg = tsubst_default_argument (fn, type, arg);
--- 3854,3864 ----
conversions. Return the converted value. */
tree
! convert_default_arg (type, arg, fn, parmnum)
tree type;
tree arg;
tree fn;
+ int parmnum;
{
if (fn && DECL_TEMPLATE_INFO (fn))
arg = tsubst_default_argument (fn, type, arg);
*************** convert_default_arg (type, arg, fn)
*** 3854,3860 ****
{
arg = digest_init (type, arg, 0);
arg = convert_for_initialization (0, type, arg, LOOKUP_NORMAL,
! "default argument", 0, 0);
}
else
{
--- 3869,3875 ----
{
arg = digest_init (type, arg, 0);
arg = convert_for_initialization (0, type, arg, LOOKUP_NORMAL,
! "default argument", fn, parmnum);
}
else
{
*************** convert_default_arg (type, arg, fn)
*** 3863,3869 ****
arg = copy_node (arg);
arg = convert_for_initialization (0, type, arg, LOOKUP_NORMAL,
! "default argument", 0, 0);
if (PROMOTE_PROTOTYPES
&& (TREE_CODE (type) == INTEGER_TYPE
|| TREE_CODE (type) == ENUMERAL_TYPE)
--- 3878,3884 ----
arg = copy_node (arg);
arg = convert_for_initialization (0, type, arg, LOOKUP_NORMAL,
! "default argument", fn, parmnum);
if (PROMOTE_PROTOTYPES
&& (TREE_CODE (type) == INTEGER_TYPE
|| TREE_CODE (type) == ENUMERAL_TYPE)
*************** build_over_call (cand, args, flags)
*** 3956,3962 ****
if (TREE_CODE (t) == USER_CONV
|| TREE_CODE (t) == AMBIG_CONV)
{
! val = convert_like (t, val);
break;
}
else if (TREE_CODE (t) == IDENTITY_CONV)
--- 3971,3977 ----
if (TREE_CODE (t) == USER_CONV
|| TREE_CODE (t) == AMBIG_CONV)
{
! val = convert_like_with_context (t, val, fn, i - is_method);
break;
}
else if (TREE_CODE (t) == IDENTITY_CONV)
*************** build_over_call (cand, args, flags)
*** 3964,3979 ****
}
val = convert_for_initialization
(NULL_TREE, type, val, LOOKUP_NORMAL,
! "argument passing", fn, i - is_method);
}
else
{
! /* Issue warnings about peculiar, but legal, uses of NULL. */
! if (ARITHMETIC_TYPE_P (TREE_VALUE (parm))
! && TREE_VALUE (arg) == null_node)
! cp_warning ("converting NULL to non-pointer type");
!
! val = convert_like (conv, TREE_VALUE (arg));
}
if (PROMOTE_PROTOTYPES
--- 3979,3991 ----
}
val = convert_for_initialization
(NULL_TREE, type, val, LOOKUP_NORMAL,
! "argument", fn, i - is_method);
}
else
{
! val = TREE_VALUE (arg);
! val = convert_like_with_context
! (conv, TREE_VALUE (arg), fn, i - is_method);
}
if (PROMOTE_PROTOTYPES
*************** build_over_call (cand, args, flags)
*** 3985,3996 ****
}
/* Default arguments */
! for (; parm && parm != void_list_node; parm = TREE_CHAIN (parm))
converted_args
= tree_cons (NULL_TREE,
convert_default_arg (TREE_VALUE (parm),
TREE_PURPOSE (parm),
! fn),
converted_args);
/* Ellipsis */
--- 3997,4008 ----
}
/* Default arguments */
! for (; parm && parm != void_list_node; parm = TREE_CHAIN (parm), i++)
converted_args
= tree_cons (NULL_TREE,
convert_default_arg (TREE_VALUE (parm),
TREE_PURPOSE (parm),
! fn, i - is_method),
converted_args);
/* Ellipsis */
Index: cp/cp-tree.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/cp-tree.h,v
retrieving revision 1.412
diff -c -3 -p -r1.412 cp-tree.h
*** cp-tree.h 2000/03/03 02:27:14 1.412
--- cp-tree.h 2000/03/05 09:49:35
*************** extern tree build_op_delete_call PARAMS
*** 3616,3622 ****
extern int can_convert PARAMS ((tree, tree));
extern int can_convert_arg PARAMS ((tree, tree, tree));
extern int enforce_access PARAMS ((tree, tree));
! extern tree convert_default_arg PARAMS ((tree, tree, tree));
extern tree convert_arg_to_ellipsis PARAMS ((tree));
extern tree build_x_va_arg PARAMS ((tree, tree));
extern tree convert_type_from_ellipsis PARAMS ((tree));
--- 3616,3622 ----
extern int can_convert PARAMS ((tree, tree));
extern int can_convert_arg PARAMS ((tree, tree, tree));
extern int enforce_access PARAMS ((tree, tree));
! extern tree convert_default_arg PARAMS ((tree, tree, tree, int));
extern tree convert_arg_to_ellipsis PARAMS ((tree));
extern tree build_x_va_arg PARAMS ((tree, tree));
extern tree convert_type_from_ellipsis PARAMS ((tree));
*************** extern tree build_const_cast PARAMS ((
*** 4407,4412 ****
--- 4407,4413 ----
extern tree build_c_cast PARAMS ((tree, tree));
extern tree build_x_modify_expr PARAMS ((tree, enum tree_code, tree));
extern tree build_modify_expr PARAMS ((tree, enum tree_code, tree));
+ extern tree dubious_conversion_warnings PARAMS ((tree, tree, const char *, tree, int));
extern tree convert_for_initialization PARAMS ((tree, tree, tree, int, const char *, tree, int));
extern void c_expand_asm_operands PARAMS ((tree, tree, tree, tree, int, char *, int));
extern void c_expand_return PARAMS ((tree));
Index: cp/typeck.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/typeck.c,v
retrieving revision 1.256
diff -c -3 -p -r1.256 typeck.c
*** typeck.c 2000/03/03 02:27:15 1.256
--- typeck.c 2000/03/05 09:49:42
*************** convert_arguments (typelist, values, fnd
*** 3215,3221 ****
tree parmval
= convert_default_arg (TREE_VALUE (typetail),
TREE_PURPOSE (typetail),
! fndecl);
if (parmval == error_mark_node)
return error_mark_node;
--- 3215,3221 ----
tree parmval
= convert_default_arg (TREE_VALUE (typetail),
TREE_PURPOSE (typetail),
! fndecl, i);
if (parmval == error_mark_node)
return error_mark_node;
*************** pfn_from_ptrmemfunc (t)
*** 6421,6426 ****
--- 6421,6479 ----
pfn_identifier, NULL_TREE, 0));
}
+ /* Expression EXPR is about to be implicitly converted to TYPE. Warn
+ if this is a potentially dangerous thing to do. Returns a possibly
+ marked EXPR. */
+
+ tree
+ dubious_conversion_warnings (type, expr, errtype, fndecl, parmnum)
+ tree type;
+ tree expr;
+ const char *errtype;
+ tree fndecl;
+ int parmnum;
+ {
+ /* Issue warnings about peculiar, but legal, uses of NULL. */
+ if (ARITHMETIC_TYPE_P (type) && expr == null_node)
+ {
+ if (fndecl)
+ cp_warning ("passing NULL used for non-pointer %s %P of `%D'",
+ errtype, parmnum, fndecl);
+ else
+ cp_warning ("%s to non-pointer type `%T' from NULL", errtype, type);
+ }
+
+ /* Warn about assigning a floating-point type to an integer type. */
+ if (TREE_CODE (TREE_TYPE (expr)) == REAL_TYPE
+ && TREE_CODE (type) == INTEGER_TYPE)
+ {
+ if (fndecl)
+ cp_warning ("passing `%T' for %s %P of `%D'",
+ TREE_TYPE (expr), errtype, parmnum, fndecl);
+ else
+ cp_warning ("%s to `%T' from `%T'", errtype, type, TREE_TYPE (expr));
+ }
+ /* And warn about assigning a negative value to an unsigned
+ variable. */
+ else if (TREE_UNSIGNED (type) && TREE_CODE (type) != BOOLEAN_TYPE)
+ {
+ if (TREE_CODE (expr) == INTEGER_CST
+ && TREE_NEGATED_INT (expr))
+ {
+ if (fndecl)
+ cp_warning ("passing negative value `%E' for %s %P of `%D'",
+ expr, errtype, parmnum, fndecl);
+ else
+ cp_warning ("%s of negative value `%E' to `%T'",
+ errtype, expr, type);
+ }
+ overflow_warning (expr);
+ if (TREE_CONSTANT (expr))
+ expr = fold (expr);
+ }
+ return expr;
+ }
+
/* Convert value RHS to type TYPE as preparation for an assignment to
an lvalue of type TYPE. ERRTYPE is a string to use in error
messages: "assignment", "return", etc. If FNDECL is non-NULL, we
*************** convert_for_assignment (type, rhs, errty
*** 6456,6467 ****
if (TREE_CODE (rhs) == TREE_LIST && TREE_VALUE (rhs) == error_mark_node)
return error_mark_node;
! /* Issue warnings about peculiar, but legal, uses of NULL. We
! do this *before* the call to decl_constant_value so as to
! avoid duplicate warnings on code like `const int I = NULL;
! f(I);'. */
! if (ARITHMETIC_TYPE_P (type) && rhs == null_node)
! cp_warning ("converting NULL to non-pointer type");
/* The RHS of an assignment cannot have void type. */
if (coder == VOID_TYPE)
--- 6509,6515 ----
if (TREE_CODE (rhs) == TREE_LIST && TREE_VALUE (rhs) == error_mark_node)
return error_mark_node;
! rhs = dubious_conversion_warnings (type, rhs, errtype, fndecl, parmnum);
/* The RHS of an assignment cannot have void type. */
if (coder == VOID_TYPE)
*************** convert_for_assignment (type, rhs, errty
*** 6475,6508 ****
rhs = DECL_INITIAL (rhs);
else if (TREE_READONLY_DECL_P (rhs))
rhs = decl_constant_value (rhs);
-
- /* Warn about assigning a floating-point type to an integer type. */
- if (coder == REAL_TYPE && codel == INTEGER_TYPE)
- {
- if (fndecl)
- cp_warning ("`%T' used for argument %P of `%D'",
- rhstype, parmnum, fndecl);
- else
- cp_warning ("%s to `%T' from `%T'", errtype, type, rhstype);
- }
- /* And warn about assigning a negative value to an unsigned
- variable. */
- else if (TREE_UNSIGNED (type) && codel != BOOLEAN_TYPE)
- {
- if (TREE_CODE (rhs) == INTEGER_CST
- && TREE_NEGATED_INT (rhs))
- {
- if (fndecl)
- cp_warning ("negative value `%E' passed as argument %P of `%D'",
- rhs, parmnum, fndecl);
- else
- cp_warning ("%s of negative value `%E' to `%T'",
- errtype, rhs, type);
- }
- overflow_warning (rhs);
- if (TREE_CONSTANT (rhs))
- rhs = fold (rhs);
- }
/* [expr.ass]
--- 6523,6528 ----
More information about the Gcc-patches
mailing list