From 8549882418f574245c42afc3a927c7da59015843 Mon Sep 17 00:00:00 2001 From: Joseph Myers Date: Wed, 23 Mar 2005 01:35:06 +0000 Subject: [PATCH] c-common.c (c_common_truthvalue_conversion): Adjust comment. * c-common.c (c_common_truthvalue_conversion): Adjust comment. Call c_common_truthvalue_conversion rather than lang_hooks.truthvalue_conversion. * c-convert.c (convert): Call c_objc_common_truthvalue_conversion. * c-objc-common.c (c_objc_common_truthvalue_conversion): Move to c-typeck.c. * c-objc-common.h (LANG_HOOKS_TRUTHVALUE_CONVERSION): Change to c_common_truthvalue_conversion. * c-parser.c (c_parser_paren_condition, c_parser_for_statement, c_parser_conditional_expression, c_parser_binary_expression): Call c_objc_common_truthvalue_conversion. * c-typeck.c (build_unary_op): Call c_objc_common_truthvalue_conversion. (build_conditional_expr): Do not call lang_hooks.truthvalue_conversion. (build_binary_op): Call c_common_truthvalue_conversion. (c_objc_common_truthvalue_conversion): Moved from c-objc-common.c. Call default_function_array_conversion instead of default_conversion. objc: * objc-act.c (next_sjlj_build_enter_and_setjmp, next_sjlj_build_catch_list, next_sjlj_build_try_catch_finally): Call c_common_truthvalue_conversion. From-SVN: r96917 --- gcc/ChangeLog | 22 ++++++++++++++++++++++ gcc/c-common.c | 30 ++++++++++++++++-------------- gcc/c-convert.c | 3 ++- gcc/c-objc-common.c | 28 ---------------------------- gcc/c-objc-common.h | 2 +- gcc/c-parser.c | 14 ++++++++------ gcc/c-typeck.c | 41 ++++++++++++++++++++++++++++++++++++----- gcc/objc/ChangeLog | 6 ++++++ gcc/objc/objc-act.c | 8 ++++---- 9 files changed, 95 insertions(+), 59 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8bd9d404a78..8f354b5cf2f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,25 @@ +2005-03-23 Joseph S. Myers + + * c-common.c (c_common_truthvalue_conversion): Adjust comment. + Call c_common_truthvalue_conversion rather than + lang_hooks.truthvalue_conversion. + * c-convert.c (convert): Call c_objc_common_truthvalue_conversion. + * c-objc-common.c (c_objc_common_truthvalue_conversion): Move to + c-typeck.c. + * c-objc-common.h (LANG_HOOKS_TRUTHVALUE_CONVERSION): Change to + c_common_truthvalue_conversion. + * c-parser.c (c_parser_paren_condition, c_parser_for_statement, + c_parser_conditional_expression, c_parser_binary_expression): Call + c_objc_common_truthvalue_conversion. + * c-typeck.c (build_unary_op): Call + c_objc_common_truthvalue_conversion. + (build_conditional_expr): Do not call + lang_hooks.truthvalue_conversion. + (build_binary_op): Call c_common_truthvalue_conversion. + (c_objc_common_truthvalue_conversion): Moved from + c-objc-common.c. Call default_function_array_conversion instead + of default_conversion. + 2005-03-23 Joseph S. Myers * c-common.h (default_conversion): Remove. diff --git a/gcc/c-common.c b/gcc/c-common.c index d4b9d5cda8e..ec7b04d6f32 100644 --- a/gcc/c-common.c +++ b/gcc/c-common.c @@ -2313,7 +2313,9 @@ pointer_int_sum (enum tree_code resultcode, tree ptrop, tree intop) } /* Prepare expr to be an argument of a TRUTH_NOT_EXPR, - or validate its data type for an `if' or `while' statement or ?..: exp. + or for an `if' or `while' statement or ?..: exp. It should already + have been validated to be of suitable type; otherwise, a bad + diagnostic may result. This preparation consists of taking the ordinary representation of an expression expr and producing a valid tree @@ -2345,14 +2347,14 @@ c_common_truthvalue_conversion (tree expr) if (TREE_TYPE (expr) == truthvalue_type_node) return expr; return build2 (TREE_CODE (expr), truthvalue_type_node, - lang_hooks.truthvalue_conversion (TREE_OPERAND (expr, 0)), - lang_hooks.truthvalue_conversion (TREE_OPERAND (expr, 1))); + c_common_truthvalue_conversion (TREE_OPERAND (expr, 0)), + c_common_truthvalue_conversion (TREE_OPERAND (expr, 1))); case TRUTH_NOT_EXPR: if (TREE_TYPE (expr) == truthvalue_type_node) return expr; return build1 (TREE_CODE (expr), truthvalue_type_node, - lang_hooks.truthvalue_conversion (TREE_OPERAND (expr, 0))); + c_common_truthvalue_conversion (TREE_OPERAND (expr, 0))); case ERROR_MARK: return expr; @@ -2400,15 +2402,15 @@ c_common_truthvalue_conversion (tree expr) case COMPLEX_EXPR: return build_binary_op ((TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 1)) ? TRUTH_OR_EXPR : TRUTH_ORIF_EXPR), - lang_hooks.truthvalue_conversion (TREE_OPERAND (expr, 0)), - lang_hooks.truthvalue_conversion (TREE_OPERAND (expr, 1)), + c_common_truthvalue_conversion (TREE_OPERAND (expr, 0)), + c_common_truthvalue_conversion (TREE_OPERAND (expr, 1)), 0); case NEGATE_EXPR: case ABS_EXPR: case FLOAT_EXPR: /* These don't change whether an object is nonzero or zero. */ - return lang_hooks.truthvalue_conversion (TREE_OPERAND (expr, 0)); + return c_common_truthvalue_conversion (TREE_OPERAND (expr, 0)); case LROTATE_EXPR: case RROTATE_EXPR: @@ -2417,16 +2419,16 @@ c_common_truthvalue_conversion (tree expr) if (TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 1))) return build2 (COMPOUND_EXPR, truthvalue_type_node, TREE_OPERAND (expr, 1), - lang_hooks.truthvalue_conversion (TREE_OPERAND (expr, 0))); + c_common_truthvalue_conversion (TREE_OPERAND (expr, 0))); else - return lang_hooks.truthvalue_conversion (TREE_OPERAND (expr, 0)); + return c_common_truthvalue_conversion (TREE_OPERAND (expr, 0)); case COND_EXPR: /* Distribute the conversion into the arms of a COND_EXPR. */ return fold (build3 (COND_EXPR, truthvalue_type_node, TREE_OPERAND (expr, 0), - lang_hooks.truthvalue_conversion (TREE_OPERAND (expr, 1)), - lang_hooks.truthvalue_conversion (TREE_OPERAND (expr, 2)))); + c_common_truthvalue_conversion (TREE_OPERAND (expr, 1)), + c_common_truthvalue_conversion (TREE_OPERAND (expr, 2)))); case CONVERT_EXPR: /* Don't cancel the effect of a CONVERT_EXPR from a REFERENCE_TYPE, @@ -2439,7 +2441,7 @@ c_common_truthvalue_conversion (tree expr) /* If this is widening the argument, we can ignore it. */ if (TYPE_PRECISION (TREE_TYPE (expr)) >= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (expr, 0)))) - return lang_hooks.truthvalue_conversion (TREE_OPERAND (expr, 0)); + return c_common_truthvalue_conversion (TREE_OPERAND (expr, 0)); break; case MINUS_EXPR: @@ -2488,8 +2490,8 @@ c_common_truthvalue_conversion (tree expr) return (build_binary_op ((TREE_SIDE_EFFECTS (expr) ? TRUTH_OR_EXPR : TRUTH_ORIF_EXPR), - lang_hooks.truthvalue_conversion (build_unary_op (REALPART_EXPR, t, 0)), - lang_hooks.truthvalue_conversion (build_unary_op (IMAGPART_EXPR, t, 0)), + c_common_truthvalue_conversion (build_unary_op (REALPART_EXPR, t, 0)), + c_common_truthvalue_conversion (build_unary_op (IMAGPART_EXPR, t, 0)), 0)); } diff --git a/gcc/c-convert.c b/gcc/c-convert.c index 3067137c372..d6bff462ede 100644 --- a/gcc/c-convert.c +++ b/gcc/c-convert.c @@ -33,6 +33,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include "flags.h" #include "convert.h" #include "c-common.h" +#include "c-tree.h" #include "langhooks.h" #include "toplev.h" @@ -95,7 +96,7 @@ convert (tree type, tree expr) return fold (convert_to_integer (type, e)); if (code == BOOLEAN_TYPE) { - tree t = lang_hooks.truthvalue_conversion (expr); + tree t = c_objc_common_truthvalue_conversion (expr); if (TREE_CODE (t) == ERROR_MARK) return t; diff --git a/gcc/c-objc-common.c b/gcc/c-objc-common.c index 89fb409878e..4b09c3e40d8 100644 --- a/gcc/c-objc-common.c +++ b/gcc/c-objc-common.c @@ -230,34 +230,6 @@ c_tree_printer (pretty_printer *pp, text_info *text) return true; } -tree -c_objc_common_truthvalue_conversion (tree expr) -{ - retry: - switch (TREE_CODE (TREE_TYPE (expr))) - { - case ARRAY_TYPE: - expr = default_conversion (expr); - if (TREE_CODE (TREE_TYPE (expr)) != ARRAY_TYPE) - goto retry; - - error ("used array that cannot be converted to pointer where scalar is required"); - return error_mark_node; - - case RECORD_TYPE: - error ("used struct type value where scalar is required"); - return error_mark_node; - - case UNION_TYPE: - error ("used union type value where scalar is required"); - return error_mark_node; - default: - break; - } - - return c_common_truthvalue_conversion (expr); -} - /* In C and ObjC, all decls have "C" linkage. */ bool has_c_linkage (tree decl ATTRIBUTE_UNUSED) diff --git a/gcc/c-objc-common.h b/gcc/c-objc-common.h index 5107dce068d..c6cca43d3c0 100644 --- a/gcc/c-objc-common.h +++ b/gcc/c-objc-common.h @@ -53,7 +53,7 @@ extern void c_initialize_diagnostics (diagnostic_context *); #undef LANG_HOOKS_PARSE_FILE #define LANG_HOOKS_PARSE_FILE c_common_parse_file #undef LANG_HOOKS_TRUTHVALUE_CONVERSION -#define LANG_HOOKS_TRUTHVALUE_CONVERSION c_objc_common_truthvalue_conversion +#define LANG_HOOKS_TRUTHVALUE_CONVERSION c_common_truthvalue_conversion #undef LANG_HOOKS_FINISH_INCOMPLETE_DECL #define LANG_HOOKS_FINISH_INCOMPLETE_DECL c_finish_incomplete_decl #undef LANG_HOOKS_REDUCE_BIT_FIELD_OPERATIONS diff --git a/gcc/c-parser.c b/gcc/c-parser.c index 99b6e090492..8e8626ef248 100644 --- a/gcc/c-parser.c +++ b/gcc/c-parser.c @@ -3580,7 +3580,8 @@ c_parser_paren_condition (c_parser *parser) if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) return error_mark_node; loc = c_parser_peek_token (parser)->location; - cond = lang_hooks.truthvalue_conversion (c_parser_expression (parser).value); + cond = c_objc_common_truthvalue_conversion + (c_parser_expression (parser).value); if (EXPR_P (cond)) SET_EXPR_LOCATION (cond, loc); c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); @@ -3816,7 +3817,7 @@ c_parser_for_statement (c_parser *parser) else { tree ocond = c_parser_expression (parser).value; - cond = lang_hooks.truthvalue_conversion (ocond); + cond = c_objc_common_truthvalue_conversion (ocond); if (EXPR_P (cond)) SET_EXPR_LOCATION (cond, loc); c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>"); @@ -4151,13 +4152,14 @@ c_parser_conditional_expression (c_parser *parser, struct c_expr *after) pedwarn ("ISO C forbids omitting the middle term of a ?: expression"); /* Make sure first operand is calculated only once. */ exp1.value = save_expr (default_conversion (cond.value)); - cond.value = lang_hooks.truthvalue_conversion (exp1.value); + cond.value = c_objc_common_truthvalue_conversion (exp1.value); skip_evaluation += cond.value == truthvalue_true_node; } else { cond.value - = lang_hooks.truthvalue_conversion (default_conversion (cond.value)); + = c_objc_common_truthvalue_conversion + (default_conversion (cond.value)); skip_evaluation += cond.value == truthvalue_false_node; exp1 = c_parser_expression (parser); skip_evaluation += ((cond.value == truthvalue_true_node) @@ -4394,12 +4396,12 @@ c_parser_binary_expression (c_parser *parser, struct c_expr *after) switch (ocode) { case TRUTH_ANDIF_EXPR: - stack[sp].expr.value = lang_hooks.truthvalue_conversion + stack[sp].expr.value = c_objc_common_truthvalue_conversion (default_conversion (stack[sp].expr.value)); skip_evaluation += stack[sp].expr.value == truthvalue_false_node; break; case TRUTH_ORIF_EXPR: - stack[sp].expr.value = lang_hooks.truthvalue_conversion + stack[sp].expr.value = c_objc_common_truthvalue_conversion (default_conversion (stack[sp].expr.value)); skip_evaluation += stack[sp].expr.value == truthvalue_true_node; break; diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c index a89c87a3601..9ddafe10c5d 100644 --- a/gcc/c-typeck.c +++ b/gcc/c-typeck.c @@ -2561,6 +2561,8 @@ build_unary_op (enum tree_code code, tree xarg, int flag) break; case TRUTH_NOT_EXPR: + /* ??? Why do most validation here but that for non-lvalue arrays + in c_objc_common_truthvalue_conversion? */ if (typecode != INTEGER_TYPE && typecode != REAL_TYPE && typecode != POINTER_TYPE && typecode != COMPLEX_TYPE @@ -2570,7 +2572,7 @@ build_unary_op (enum tree_code code, tree xarg, int flag) error ("wrong type argument to unary exclamation mark"); return error_mark_node; } - arg = lang_hooks.truthvalue_conversion (arg); + arg = c_objc_common_truthvalue_conversion (arg); return invert_truthvalue (arg); case NOP_EXPR: @@ -2926,8 +2928,6 @@ build_conditional_expr (tree ifexp, tree op1, tree op2) tree result_type = NULL; tree orig_op1 = op1, orig_op2 = op2; - ifexp = lang_hooks.truthvalue_conversion (default_conversion (ifexp)); - /* Promote both alternatives. */ if (TREE_CODE (TREE_TYPE (op1)) != VOID_TYPE) @@ -7316,8 +7316,8 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1, but that does not mean the operands should be converted to ints! */ result_type = integer_type_node; - op0 = lang_hooks.truthvalue_conversion (op0); - op1 = lang_hooks.truthvalue_conversion (op1); + op0 = c_common_truthvalue_conversion (op0); + op1 = c_common_truthvalue_conversion (op1); converted = 1; } break; @@ -7797,3 +7797,34 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1, return result; } } + + +/* Convert EXPR to be a truth-value, validating its type for this + purpose. Passes EXPR to default_function_array_conversion. */ + +tree +c_objc_common_truthvalue_conversion (tree expr) +{ + expr = default_function_array_conversion (expr); + switch (TREE_CODE (TREE_TYPE (expr))) + { + case ARRAY_TYPE: + error ("used array that cannot be converted to pointer where scalar is required"); + return error_mark_node; + + case RECORD_TYPE: + error ("used struct type value where scalar is required"); + return error_mark_node; + + case UNION_TYPE: + error ("used union type value where scalar is required"); + return error_mark_node; + + default: + break; + } + + /* ??? Should we also give an error for void and vectors rather than + leaving those to give errors later? */ + return c_common_truthvalue_conversion (expr); +} diff --git a/gcc/objc/ChangeLog b/gcc/objc/ChangeLog index 49e73af4960..00df6c3dffd 100644 --- a/gcc/objc/ChangeLog +++ b/gcc/objc/ChangeLog @@ -1,3 +1,9 @@ +2005-03-23 Joseph S. Myers + + * objc-act.c (next_sjlj_build_enter_and_setjmp, + next_sjlj_build_catch_list, next_sjlj_build_try_catch_finally): + Call c_common_truthvalue_conversion. + 2005-02-25 Joseph S. Myers * Make-lang.in (objc/objc-parse.o-warn, objc/objc-parse.o, diff --git a/gcc/objc/objc-act.c b/gcc/objc/objc-act.c index e6201afbad5..1848e3c6c47 100644 --- a/gcc/objc/objc-act.c +++ b/gcc/objc/objc-act.c @@ -3019,7 +3019,7 @@ next_sjlj_build_enter_and_setjmp (void) sj = build_function_call (objc_setjmp_decl, t); cond = build (COMPOUND_EXPR, TREE_TYPE (sj), enter, sj); - cond = lang_hooks.truthvalue_conversion (cond); + cond = c_common_truthvalue_conversion (cond); return build (COND_EXPR, void_type_node, cond, NULL, NULL); } @@ -3086,7 +3086,7 @@ next_sjlj_build_catch_list (void) t = objc_get_class_reference (OBJC_TYPE_NAME (TREE_TYPE (type))); args = tree_cons (NULL, t, args); t = build_function_call (objc_exception_match_decl, args); - cond = lang_hooks.truthvalue_conversion (t); + cond = c_common_truthvalue_conversion (t); } t = build (COND_EXPR, void_type_node, cond, body, NULL); SET_EXPR_LOCUS (t, EXPR_LOCUS (stmt)); @@ -3208,7 +3208,7 @@ next_sjlj_build_try_catch_finally (void) /* Build the complete FINALLY statement list. */ t = next_sjlj_build_try_exit (); t = build_stmt (COND_EXPR, - lang_hooks.truthvalue_conversion (rethrow_decl), + c_common_truthvalue_conversion (rethrow_decl), NULL, t); SET_EXPR_LOCATION (t, cur_try_context->finally_locus); append_to_statement_list (t, &TREE_OPERAND (try_fin, 1)); @@ -3219,7 +3219,7 @@ next_sjlj_build_try_catch_finally (void) t = tree_cons (NULL, rethrow_decl, NULL); t = build_function_call (objc_exception_throw_decl, t); t = build_stmt (COND_EXPR, - lang_hooks.truthvalue_conversion (rethrow_decl), + c_common_truthvalue_conversion (rethrow_decl), t, NULL); SET_EXPR_LOCATION (t, cur_try_context->end_finally_locus); append_to_statement_list (t, &TREE_OPERAND (try_fin, 1)); -- 2.30.2