2005-03-23 Joseph S. Myers <joseph@codesourcery.com>
+ * 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 <joseph@codesourcery.com>
+
* c-common.h (default_conversion): Remove.
(perform_integral_promotions): Add.
* c-tree.h (default_conversion): Add.
}
\f
/* 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
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;
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:
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,
/* 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:
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));
}
#include "flags.h"
#include "convert.h"
#include "c-common.h"
+#include "c-tree.h"
#include "langhooks.h"
#include "toplev.h"
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;
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)
#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
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 %<)%>");
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 %<;%>");
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)
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;
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
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:
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)
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;
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);
+}
+2005-03-23 Joseph S. Myers <joseph@codesourcery.com>
+
+ * 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 <joseph@codesourcery.com>
* Make-lang.in (objc/objc-parse.o-warn, objc/objc-parse.o,
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);
}
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));
/* 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));
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));