diff options
author | Nathan Sidwell <nathan@codesourcery.com> | 2000-03-05 10:22:16 +0000 |
---|---|---|
committer | Nathan Sidwell <nathan@gcc.gnu.org> | 2000-03-05 10:22:16 +0000 |
commit | c3f082287cde52571c84a7c18f455bdc2e34f7fe (patch) | |
tree | 5ff56b9f3a4de9b423c89fa746c6586c5497c90e /gcc | |
parent | 18ca9ce7234bb110f3a8aaaae334955cf49d17e5 (diff) | |
download | gcc-c3f082287cde52571c84a7c18f455bdc2e34f7fe.zip gcc-c3f082287cde52571c84a7c18f455bdc2e34f7fe.tar.gz gcc-c3f082287cde52571c84a7c18f455bdc2e34f7fe.tar.bz2 |
call.c (convert_like): Macrofy.
* 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.
From-SVN: r32341
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 19 | ||||
-rw-r--r-- | gcc/cp/call.c | 58 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 3 | ||||
-rw-r--r-- | gcc/cp/typeck.c | 90 |
4 files changed, 111 insertions, 59 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index b97b555..2213278 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,22 @@ +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. + 2000-03-03 Jason Merrill <jason@casey.cygnus.com> * decl2.c (key_method): Break out from... diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 72c4ccb..0589cfd 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -49,7 +49,9 @@ static int equal_functions PARAMS ((tree, tree)); 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)); +#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)); @@ -2450,7 +2452,9 @@ build_user_type_conversion (totype, expr, flags) { if (TREE_CODE (cand->second_conv) == AMBIG_CONV) return error_mark_node; - return convert_from_reference (convert_like (cand->second_conv, expr)); + return convert_from_reference + (convert_like_with_context + (cand->second_conv, expr, cand->fn, 0)); } return NULL_TREE; } @@ -2654,7 +2658,8 @@ build_object_call (obj, args) && 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); + obj = convert_like_with_context + (TREE_VEC_ELT (cand->convs, 0), obj, cand->fn, -1); /* FIXME */ return build_function_call (obj, args); @@ -3593,11 +3598,17 @@ enforce_access (basetype_path, decl) return 1; } -/* Perform the conversions in CONVS on the expression EXPR. */ +/* 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 (convs, expr) +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 @@ -3609,19 +3620,22 @@ convert_like (convs, expr) { if (TREE_CODE (t) == USER_CONV) { - expr = convert_like (t, expr); + expr = convert_like_real (t, expr, fn, argnum, 1); break; } else if (TREE_CODE (t) == AMBIG_CONV) - return convert_like (t, expr); + 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", NULL_TREE, 0); + "conversion", fn, argnum); } - + + if (!inner) + expr = dubious_conversion_warnings + (TREE_TYPE (convs), expr, "argument", fn, argnum); switch (TREE_CODE (convs)) { case USER_CONV: @@ -3665,7 +3679,7 @@ convert_like (convs, expr) break; }; - expr = convert_like (TREE_OPERAND (convs, 0), expr); + expr = convert_like_real (TREE_OPERAND (convs, 0), expr, fn, argnum, 1); if (expr == error_mark_node) return error_mark_node; @@ -3840,10 +3854,11 @@ convert_type_from_ellipsis (type) conversions. Return the converted value. */ tree -convert_default_arg (type, arg, fn) +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); @@ -3854,7 +3869,7 @@ convert_default_arg (type, arg, fn) { arg = digest_init (type, arg, 0); arg = convert_for_initialization (0, type, arg, LOOKUP_NORMAL, - "default argument", 0, 0); + "default argument", fn, parmnum); } else { @@ -3863,7 +3878,7 @@ convert_default_arg (type, arg, fn) arg = copy_node (arg); arg = convert_for_initialization (0, type, arg, LOOKUP_NORMAL, - "default argument", 0, 0); + "default argument", fn, parmnum); if (PROMOTE_PROTOTYPES && (TREE_CODE (type) == INTEGER_TYPE || TREE_CODE (type) == ENUMERAL_TYPE) @@ -3956,7 +3971,7 @@ build_over_call (cand, args, flags) if (TREE_CODE (t) == USER_CONV || TREE_CODE (t) == AMBIG_CONV) { - val = convert_like (t, val); + val = convert_like_with_context (t, val, fn, i - is_method); break; } else if (TREE_CODE (t) == IDENTITY_CONV) @@ -3964,16 +3979,13 @@ build_over_call (cand, args, flags) } val = convert_for_initialization (NULL_TREE, type, val, LOOKUP_NORMAL, - "argument passing", fn, i - is_method); + "argument", 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)); + val = TREE_VALUE (arg); + val = convert_like_with_context + (conv, TREE_VALUE (arg), fn, i - is_method); } if (PROMOTE_PROTOTYPES @@ -3985,12 +3997,12 @@ build_over_call (cand, args, flags) } /* Default arguments */ - for (; parm && parm != void_list_node; parm = TREE_CHAIN (parm)) + 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), + fn, i - is_method), converted_args); /* Ellipsis */ diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index ce2b94c..9086292 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -3616,7 +3616,7 @@ extern tree build_op_delete_call PARAMS ((enum tree_code, tree, tree, int, tree 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_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)); @@ -4407,6 +4407,7 @@ extern tree build_const_cast PARAMS ((tree, tree)); 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)); diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 400d930..219ca39 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -3215,7 +3215,7 @@ convert_arguments (typelist, values, fndecl, flags) tree parmval = convert_default_arg (TREE_VALUE (typetail), TREE_PURPOSE (typetail), - fndecl); + fndecl, i); if (parmval == error_mark_node) return error_mark_node; @@ -6421,6 +6421,59 @@ pfn_from_ptrmemfunc (t) 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 @@ -6456,12 +6509,7 @@ convert_for_assignment (type, rhs, errtype, fndecl, parmnum) 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"); + rhs = dubious_conversion_warnings (type, rhs, errtype, fndecl, parmnum); /* The RHS of an assignment cannot have void type. */ if (coder == VOID_TYPE) @@ -6476,34 +6524,6 @@ convert_for_assignment (type, rhs, errtype, fndecl, parmnum) 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] The expression is implicitly converted (clause _conv_) to the |