/* Build expressions with type checking for C compiler.
- Copyright (C) 1987, 88, 91-97, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1987, 1988, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
+ 1998, 1999, 2000 Free Software Foundation, Inc.
This file is part of GNU CC.
#include "system.h"
#include "tree.h"
#include "c-tree.h"
+#include "tm_p.h"
#include "flags.h"
#include "output.h"
#include "rtl.h"
#include "expr.h"
#include "toplev.h"
+#include "intl.h"
+#include "defaults.h"
+#include "ggc.h"
/* Nonzero if we've already printed a "missing braces around initializer"
message within this initializer. */
static int missing_braces_mentioned;
-static tree qualify_type PROTO((tree, tree));
-static int comp_target_types PROTO((tree, tree));
-static int function_types_compatible_p PROTO((tree, tree));
-static int type_lists_compatible_p PROTO((tree, tree));
-static int self_promoting_type_p PROTO((tree));
-static tree decl_constant_value PROTO((tree));
-static tree lookup_field PROTO((tree, tree, tree *));
-static tree convert_arguments PROTO((tree, tree, tree, tree));
-static tree pointer_int_sum PROTO((enum tree_code, tree, tree));
-static tree pointer_diff PROTO((tree, tree));
-static tree unary_complex_lvalue PROTO((enum tree_code, tree));
-static void pedantic_lvalue_warning PROTO((enum tree_code));
-static tree internal_build_compound_expr PROTO((tree, int));
-static tree convert_for_assignment PROTO((tree, tree, char *, tree,
- tree, int));
-static void warn_for_assignment PROTO((char *, char *, tree, int));
-static tree valid_compound_expr_initializer PROTO((tree, tree));
-static void push_string PROTO((char *));
-static void push_member_name PROTO((tree));
-static void push_array_bounds PROTO((int));
-static int spelling_length PROTO((void));
-static char *print_spelling PROTO((char *));
-static char *get_spelling PROTO((char *));
-static void warning_init PROTO((char *, char *,
- char *));
-static tree digest_init PROTO((tree, tree, int, int));
-static void check_init_type_bitfields PROTO((tree));
-static void output_init_element PROTO((tree, tree, tree, int));
-static void output_pending_init_elements PROTO((int));
-static void add_pending_init PROTO((tree, tree));
-static int pending_init_member PROTO((tree));
+static tree qualify_type PARAMS ((tree, tree));
+static int comp_target_types PARAMS ((tree, tree));
+static int function_types_compatible_p PARAMS ((tree, tree));
+static int type_lists_compatible_p PARAMS ((tree, tree));
+static tree decl_constant_value PARAMS ((tree));
+static tree lookup_field PARAMS ((tree, tree, tree *));
+static tree convert_arguments PARAMS ((tree, tree, tree, tree));
+static tree pointer_int_sum PARAMS ((enum tree_code, tree, tree));
+static tree pointer_diff PARAMS ((tree, tree));
+static tree unary_complex_lvalue PARAMS ((enum tree_code, tree));
+static void pedantic_lvalue_warning PARAMS ((enum tree_code));
+static tree internal_build_compound_expr PARAMS ((tree, int));
+static tree convert_for_assignment PARAMS ((tree, tree, const char *,
+ tree, tree, int));
+static void warn_for_assignment PARAMS ((const char *, const char *,
+ tree, int));
+static tree valid_compound_expr_initializer PARAMS ((tree, tree));
+static void push_string PARAMS ((const char *));
+static void push_member_name PARAMS ((tree));
+static void push_array_bounds PARAMS ((int));
+static int spelling_length PARAMS ((void));
+static char *print_spelling PARAMS ((char *));
+static void warning_init PARAMS ((const char *));
+static tree digest_init PARAMS ((tree, tree, int, int));
+static void check_init_type_bitfields PARAMS ((tree));
+static void output_init_element PARAMS ((tree, tree, tree, int));
+static void output_pending_init_elements PARAMS ((int));
+static void add_pending_init PARAMS ((tree, tree));
+static int pending_init_member PARAMS ((tree));
\f
/* Do `exp = require_complete_type (exp);' to make sure exp
does not have an incomplete type. (That includes void types.) */
{
tree type = TREE_TYPE (value);
+ if (TREE_CODE (value) == ERROR_MARK)
+ return error_mark_node;
+
/* First, detect a valid value with a complete type. */
- if (TYPE_SIZE (type) != 0
- && type != void_type_node)
+ if (COMPLETE_TYPE_P (type))
return value;
incomplete_type_error (value, type);
tree value;
tree type;
{
- char *errmsg;
+ const char *type_code_string;
/* Avoid duplicate error message. */
if (TREE_CODE (type) == ERROR_MARK)
switch (TREE_CODE (type))
{
case RECORD_TYPE:
- errmsg = "invalid use of undefined type `struct %s'";
+ type_code_string = "struct";
break;
case UNION_TYPE:
- errmsg = "invalid use of undefined type `union %s'";
+ type_code_string = "union";
break;
case ENUMERAL_TYPE:
- errmsg = "invalid use of undefined type `enum %s'";
+ type_code_string = "enum";
break;
case VOID_TYPE:
}
if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE)
- error (errmsg, IDENTIFIER_POINTER (TYPE_NAME (type)));
+ error ("invalid use of undefined type `%s %s'",
+ type_code_string, IDENTIFIER_POINTER (TYPE_NAME (type)));
else
/* If this type has a typedef-name, the TYPE_NAME is a TYPE_DECL. */
error ("invalid use of incomplete typedef `%s'",
qualify_type (type, like)
tree type, like;
{
- int constflag = TYPE_READONLY (type) || TYPE_READONLY (like);
- int volflag = TYPE_VOLATILE (type) || TYPE_VOLATILE (like);
- return c_build_type_variant (type, constflag, volflag);
+ return c_build_qualified_type (type,
+ TYPE_QUALS (type) | TYPE_QUALS (like));
}
\f
/* Return the common type of two types.
But ANSI C specifies doing this with the qualifiers.
So I turned it on again. */
{
- tree target = common_type (TYPE_MAIN_VARIANT (TREE_TYPE (t1)),
- TYPE_MAIN_VARIANT (TREE_TYPE (t2)));
- int constp
- = TYPE_READONLY (TREE_TYPE (t1)) || TYPE_READONLY (TREE_TYPE (t2));
- int volatilep
- = TYPE_VOLATILE (TREE_TYPE (t1)) || TYPE_VOLATILE (TREE_TYPE (t2));
- t1 = build_pointer_type (c_build_type_variant (target, constp,
- volatilep));
+ tree pointed_to_1 = TREE_TYPE (t1);
+ tree pointed_to_2 = TREE_TYPE (t2);
+ tree target = common_type (TYPE_MAIN_VARIANT (pointed_to_1),
+ TYPE_MAIN_VARIANT (pointed_to_2));
+ t1 = build_pointer_type (c_build_qualified_type
+ (target,
+ TYPE_QUALS (pointed_to_1) |
+ TYPE_QUALS (pointed_to_2)));
return build_type_attribute_variant (t1, attributes);
}
#if 0
|| TREE_CODE (t1) == ERROR_MARK || TREE_CODE (t2) == ERROR_MARK)
return 1;
+ /* If either type is the internal version of sizetype, return the
+ language version. */
+ if (TREE_CODE (t1) == INTEGER_TYPE && TYPE_IS_SIZETYPE (t1)
+ && TYPE_DOMAIN (t1) != 0)
+ t1 = TYPE_DOMAIN (t1);
+
+ if (TREE_CODE (t2) == INTEGER_TYPE && TYPE_IS_SIZETYPE (t2)
+ && TYPE_DOMAIN (t2) != 0)
+ t2 = TYPE_DOMAIN (t2);
+
/* Treat an enum type as the integer type of the same width and
signedness. */
/* Qualifiers must match. */
- if (TYPE_READONLY (t1) != TYPE_READONLY (t2))
- return 0;
- if (TYPE_VOLATILE (t1) != TYPE_VOLATILE (t2))
+ if (TYPE_QUALS (t1) != TYPE_QUALS (t2))
return 0;
/* Allow for two different type nodes which have essentially the same
|| TREE_CODE (TYPE_MAX_VALUE (d2)) != INTEGER_CST)
break;
- if (! ((TREE_INT_CST_LOW (TYPE_MIN_VALUE (d1))
- == TREE_INT_CST_LOW (TYPE_MIN_VALUE (d2)))
- && (TREE_INT_CST_HIGH (TYPE_MIN_VALUE (d1))
- == TREE_INT_CST_HIGH (TYPE_MIN_VALUE (d2)))
- && (TREE_INT_CST_LOW (TYPE_MAX_VALUE (d1))
- == TREE_INT_CST_LOW (TYPE_MAX_VALUE (d2)))
- && (TREE_INT_CST_HIGH (TYPE_MAX_VALUE (d1))
- == TREE_INT_CST_HIGH (TYPE_MAX_VALUE (d2)))))
- val = 0;
+ if (! tree_int_cst_equal (TYPE_MIN_VALUE (d1), TYPE_MIN_VALUE (d2))
+ || ! tree_int_cst_equal (TYPE_MAX_VALUE (d1), TYPE_MAX_VALUE (d2)))
+ val = 0;
+
break;
}
So match anything that self-promotes. */
if (TREE_VALUE (args1) == 0)
{
- if (! self_promoting_type_p (TREE_VALUE (args2)))
+ if (simple_type_promotes_to (TREE_VALUE (args2)) != NULL_TREE)
return 0;
}
else if (TREE_VALUE (args2) == 0)
{
- if (! self_promoting_type_p (TREE_VALUE (args1)))
+ if (simple_type_promotes_to (TREE_VALUE (args1)) != NULL_TREE)
return 0;
}
else if (! (newval = comptypes (TREE_VALUE (args1), TREE_VALUE (args2))))
args2 = TREE_CHAIN (args2);
}
}
-
-/* Return 1 if PARMS specifies a fixed number of parameters
- and none of their types is affected by default promotions. */
-
-int
-self_promoting_args_p (parms)
- tree parms;
-{
- register tree t;
- for (t = parms; t; t = TREE_CHAIN (t))
- {
- register tree type = TREE_VALUE (t);
-
- if (TREE_CHAIN (t) == 0 && type != void_type_node)
- return 0;
-
- if (type == 0)
- return 0;
-
- if (TYPE_MAIN_VARIANT (type) == float_type_node)
- return 0;
-
- if (C_PROMOTING_INTEGER_TYPE_P (type))
- return 0;
- }
- return 1;
-}
-
-/* Return 1 if TYPE is not affected by default promotions. */
-
-static int
-self_promoting_type_p (type)
- tree type;
-{
- if (TYPE_MAIN_VARIANT (type) == float_type_node)
- return 0;
-
- if (C_PROMOTING_INTEGER_TYPE_P (type))
- return 0;
-
- return 1;
-}
\f
-/* Return an unsigned type the same as TYPE in other respects. */
-
-tree
-unsigned_type (type)
- tree type;
-{
- tree type1 = TYPE_MAIN_VARIANT (type);
- if (type1 == signed_char_type_node || type1 == char_type_node)
- return unsigned_char_type_node;
- if (type1 == integer_type_node)
- return unsigned_type_node;
- if (type1 == short_integer_type_node)
- return short_unsigned_type_node;
- if (type1 == long_integer_type_node)
- return long_unsigned_type_node;
- if (type1 == long_long_integer_type_node)
- return long_long_unsigned_type_node;
- if (type1 == intDI_type_node)
- return unsigned_intDI_type_node;
- if (type1 == intSI_type_node)
- return unsigned_intSI_type_node;
- if (type1 == intHI_type_node)
- return unsigned_intHI_type_node;
- if (type1 == intQI_type_node)
- return unsigned_intQI_type_node;
-
- return signed_or_unsigned_type (1, type);
-}
-
-/* Return a signed type the same as TYPE in other respects. */
-
-tree
-signed_type (type)
- tree type;
-{
- tree type1 = TYPE_MAIN_VARIANT (type);
- if (type1 == unsigned_char_type_node || type1 == char_type_node)
- return signed_char_type_node;
- if (type1 == unsigned_type_node)
- return integer_type_node;
- if (type1 == short_unsigned_type_node)
- return short_integer_type_node;
- if (type1 == long_unsigned_type_node)
- return long_integer_type_node;
- if (type1 == long_long_unsigned_type_node)
- return long_long_integer_type_node;
- if (type1 == unsigned_intDI_type_node)
- return intDI_type_node;
- if (type1 == unsigned_intSI_type_node)
- return intSI_type_node;
- if (type1 == unsigned_intHI_type_node)
- return intHI_type_node;
- if (type1 == unsigned_intQI_type_node)
- return intQI_type_node;
-
- return signed_or_unsigned_type (0, type);
-}
-
-/* Return a type the same as TYPE except unsigned or
- signed according to UNSIGNEDP. */
-
-tree
-signed_or_unsigned_type (unsignedp, type)
- int unsignedp;
- tree type;
-{
- if ((! INTEGRAL_TYPE_P (type) && ! POINTER_TYPE_P (type))
- || TREE_UNSIGNED (type) == unsignedp)
- return type;
- if (TYPE_PRECISION (type) == TYPE_PRECISION (signed_char_type_node))
- return unsignedp ? unsigned_char_type_node : signed_char_type_node;
- if (TYPE_PRECISION (type) == TYPE_PRECISION (integer_type_node))
- return unsignedp ? unsigned_type_node : integer_type_node;
- if (TYPE_PRECISION (type) == TYPE_PRECISION (short_integer_type_node))
- return unsignedp ? short_unsigned_type_node : short_integer_type_node;
- if (TYPE_PRECISION (type) == TYPE_PRECISION (long_integer_type_node))
- return unsignedp ? long_unsigned_type_node : long_integer_type_node;
- if (TYPE_PRECISION (type) == TYPE_PRECISION (long_long_integer_type_node))
- return (unsignedp ? long_long_unsigned_type_node
- : long_long_integer_type_node);
- return type;
-}
-
/* Compute the value of the `sizeof' operator. */
tree
tree type;
{
enum tree_code code = TREE_CODE (type);
- tree t;
if (code == FUNCTION_TYPE)
{
if (pedantic || warn_pointer_arith)
pedwarn ("sizeof applied to a function type");
- return size_int (1);
+ return size_one_node;
}
if (code == VOID_TYPE)
{
if (pedantic || warn_pointer_arith)
pedwarn ("sizeof applied to a void type");
- return size_int (1);
+ return size_one_node;
}
+
if (code == ERROR_MARK)
- return size_int (1);
- if (TYPE_SIZE (type) == 0)
+ return size_one_node;
+
+ if (!COMPLETE_TYPE_P (type))
{
error ("sizeof applied to an incomplete type");
- return size_int (0);
+ return size_zero_node;
}
/* Convert in case a char is more than one unit. */
- t = size_binop (CEIL_DIV_EXPR, TYPE_SIZE (type),
- size_int (TYPE_PRECISION (char_type_node)));
- t = convert (sizetype, t);
- /* size_binop does not put the constant in range, so do it now. */
- if (TREE_CODE (t) == INTEGER_CST && force_fit_type (t, 0))
- TREE_CONSTANT_OVERFLOW (t) = TREE_OVERFLOW (t) = 1;
- return t;
+ return size_binop (CEIL_DIV_EXPR, TYPE_SIZE_UNIT (type),
+ size_int (TYPE_PRECISION (char_type_node)
+ / BITS_PER_UNIT));
}
tree
tree type;
{
enum tree_code code = TREE_CODE (type);
- tree t;
- if (code == FUNCTION_TYPE
- || code == VOID_TYPE
- || code == ERROR_MARK)
- return size_int (1);
- if (TYPE_SIZE (type) == 0)
- return size_int (0);
+ if (code == FUNCTION_TYPE || code == VOID_TYPE || code == ERROR_MARK)
+ return size_one_node;
+
+ if (!COMPLETE_TYPE_P (type))
+ return size_zero_node;
/* Convert in case a char is more than one unit. */
- t = size_binop (CEIL_DIV_EXPR, TYPE_SIZE (type),
- size_int (TYPE_PRECISION (char_type_node)));
- t = convert (sizetype, t);
- force_fit_type (t, 0);
- return t;
+ return size_binop (CEIL_DIV_EXPR, TYPE_SIZE_UNIT (type),
+ size_int (TYPE_PRECISION (char_type_node)
+ / BITS_PER_UNIT));
}
/* Compute the size to increment a pointer by. */
tree type;
{
enum tree_code code = TREE_CODE (type);
- tree t;
- if (code == FUNCTION_TYPE)
- return size_int (1);
- if (code == VOID_TYPE)
- return size_int (1);
- if (code == ERROR_MARK)
- return size_int (1);
- if (TYPE_SIZE (type) == 0)
+ if (code == FUNCTION_TYPE || code == VOID_TYPE || code == ERROR_MARK)
+ return size_one_node;
+
+ if (!COMPLETE_OR_VOID_TYPE_P (type))
{
error ("arithmetic on pointer to an incomplete type");
- return size_int (1);
+ return size_one_node;
}
/* Convert in case a char is more than one unit. */
- t = size_binop (CEIL_DIV_EXPR, TYPE_SIZE (type),
- size_int (BITS_PER_UNIT));
- t = convert (sizetype, t);
- force_fit_type (t, 0);
- return t;
+ return size_binop (CEIL_DIV_EXPR, TYPE_SIZE_UNIT (type),
+ size_int (TYPE_PRECISION (char_type_node)
+ / BITS_PER_UNIT));
}
/* Implement the __alignof keyword: Return the minimum required
return size_int (FUNCTION_BOUNDARY / BITS_PER_UNIT);
if (code == VOID_TYPE || code == ERROR_MARK)
- return size_int (1);
+ return size_one_node;
+
+ if (!COMPLETE_TYPE_P (type))
+ {
+ error ("__alignof__ applied to an incomplete type");
+ return size_zero_node;
+ }
return size_int (TYPE_ALIGN (type) / BITS_PER_UNIT);
}
&& DECL_C_BIT_FIELD (TREE_OPERAND (expr, 1)))
{
error ("`__alignof' applied to a bit-field");
- return size_int (1);
+ return size_one_node;
}
else if (TREE_CODE (expr) == COMPONENT_REF
&& TREE_CODE (TREE_OPERAND (expr, 1)) == FIELD_DECL)
}
/* Strip NON_LVALUE_EXPRs and no-op conversions, since we aren't using as
- an lvalue. */
- /* Do not use STRIP_NOPS here! It will remove conversions from pointer
+ an lvalue.
+
+ Do not use STRIP_NOPS here! It will remove conversions from pointer
to integer and cause infinite recursion. */
while (TREE_CODE (exp) == NON_LVALUE_EXPR
|| (TREE_CODE (exp) == NOP_EXPR
|| (TYPE_PRECISION (type)
>= TYPE_PRECISION (integer_type_node)))
&& TREE_UNSIGNED (type)));
+
return convert (type, exp);
}
if (TREE_CODE (exp) == COMPONENT_REF
- && DECL_C_BIT_FIELD (TREE_OPERAND (exp, 1)))
- {
- tree width = DECL_SIZE (TREE_OPERAND (exp, 1));
- HOST_WIDE_INT low = TREE_INT_CST_LOW (width);
-
+ && DECL_C_BIT_FIELD (TREE_OPERAND (exp, 1))
/* If it's thinner than an int, promote it like a
C_PROMOTING_INTEGER_TYPE_P, otherwise leave it alone. */
-
- if (low < TYPE_PRECISION (integer_type_node))
- {
- if (flag_traditional && TREE_UNSIGNED (type))
- return convert (unsigned_type_node, exp);
- else
- return convert (integer_type_node, exp);
- }
- }
+ && 0 > compare_tree_int (DECL_SIZE (TREE_OPERAND (exp, 1)),
+ TYPE_PRECISION (integer_type_node)))
+ return convert (flag_traditional && TREE_UNSIGNED (type)
+ ? unsigned_type_node : integer_type_node,
+ exp);
if (C_PROMOTING_INTEGER_TYPE_P (type))
{
&& (flag_traditional
|| TYPE_PRECISION (type) == TYPE_PRECISION (integer_type_node)))
return convert (unsigned_type_node, exp);
+
return convert (integer_type_node, exp);
}
+
if (flag_traditional && !flag_allow_single_precision
&& TYPE_MAIN_VARIANT (type) == float_type_node)
return convert (double_type_node, exp);
+
if (code == VOID_TYPE)
{
error ("void value not ignored as it ought to be");
int constp = 0;
int volatilep = 0;
- if (TREE_CODE_CLASS (TREE_CODE (exp)) == 'r'
- || TREE_CODE_CLASS (TREE_CODE (exp)) == 'd')
+ if (TREE_CODE_CLASS (TREE_CODE (exp)) == 'r' || DECL_P (exp))
{
constp = TREE_READONLY (exp);
volatilep = TREE_THIS_VOLATILE (exp);
}
- if (TYPE_READONLY (type) || TYPE_VOLATILE (type)
- || constp || volatilep)
- restype = c_build_type_variant (restype,
- TYPE_READONLY (type) || constp,
- TYPE_VOLATILE (type) || volatilep);
+ if (TYPE_QUALS (type) || constp || volatilep)
+ restype
+ = c_build_qualified_type (restype,
+ TYPE_QUALS (type)
+ | (constp * TYPE_QUAL_CONST)
+ | (volatilep * TYPE_QUAL_VOLATILE));
if (TREE_CODE (exp) == INDIRECT_REF)
return convert (TYPE_POINTER_TO (restype),
{
tree indirect = 0;
- if (TYPE_SIZE (type) == 0)
+ if (!COMPLETE_TYPE_P (type))
{
incomplete_type_error (NULL_TREE, type);
return error_mark_node;
if (!field)
{
- error (code == RECORD_TYPE
- ? "structure has no member named `%s'"
- : "union has no member named `%s'",
+ error ("%s has no member named `%s'",
+ code == RECORD_TYPE ? "structure" : "union",
IDENTIFIER_POINTER (component));
return error_mark_node;
}
tree
build_indirect_ref (ptr, errorstring)
tree ptr;
- char *errorstring;
+ const char *errorstring;
{
register tree pointer = default_conversion (ptr);
register tree type = TREE_TYPE (pointer);
register tree ref = build1 (INDIRECT_REF,
TYPE_MAIN_VARIANT (t), pointer);
- if (TYPE_SIZE (t) == 0 && TREE_CODE (t) != ARRAY_TYPE)
+ if (!COMPLETE_TYPE_P (t) && TREE_CODE (t) != ARRAY_TYPE)
{
error ("dereferencing pointer to incomplete type");
return error_mark_node;
address arithmetic on its address.
Likewise an array of elements of variable size. */
if (TREE_CODE (index) != INTEGER_CST
- || (TYPE_SIZE (TREE_TYPE (TREE_TYPE (array))) != 0
+ || (COMPLETE_TYPE_P (TREE_TYPE (TREE_TYPE (array)))
&& TREE_CODE (TYPE_SIZE (TREE_TYPE (TREE_TYPE (array)))) != INTEGER_CST))
{
if (mark_addressable (array) == 0)
{
register tree fntype, fundecl = 0;
register tree coerced_params;
- tree name = NULL_TREE, assembler_name = NULL_TREE;
+ tree name = NULL_TREE, assembler_name = NULL_TREE, result;
/* Strip NON_LVALUE_EXPRs, etc., since we aren't using as an lvalue. */
STRIP_TYPE_NOPS (function);
if (TREE_CODE (function) == ADDR_EXPR
&& TREE_CODE (TREE_OPERAND (function, 0)) == FUNCTION_DECL
&& DECL_BUILT_IN (TREE_OPERAND (function, 0)))
- switch (DECL_FUNCTION_CODE (TREE_OPERAND (function, 0)))
- {
- case BUILT_IN_ABS:
- case BUILT_IN_LABS:
- case BUILT_IN_FABS:
- if (coerced_params == 0)
- return integer_zero_node;
- return build_unary_op (ABS_EXPR, TREE_VALUE (coerced_params), 0);
- default:
- break;
- }
+ {
+ result = expand_tree_builtin (TREE_OPERAND (function, 0),
+ params, coerced_params);
+ if (result)
+ return result;
+ }
- {
- register tree result
- = build (CALL_EXPR, TREE_TYPE (fntype),
- function, coerced_params, NULL_TREE);
-
- TREE_SIDE_EFFECTS (result) = 1;
- if (TREE_TYPE (result) == void_type_node)
- return result;
- return require_complete_type (result);
- }
+ result = build (CALL_EXPR, TREE_TYPE (fntype),
+ function, coerced_params, NULL_TREE);
+
+ TREE_SIDE_EFFECTS (result) = 1;
+ if (TREE_TYPE (result) == void_type_node)
+ return result;
+ return require_complete_type (result);
}
\f
/* Convert the argument expressions in the list VALUES
/* Formal parm type is specified by a function prototype. */
tree parmval;
- if (TYPE_SIZE (type) == 0)
+ if (!COMPLETE_TYPE_P (type))
{
error ("type of formal parameter %d is incomplete", parmnum + 1);
parmval = val;
(char *) 0, /* arg passing */
fundecl, name, parmnum + 1);
-#ifdef PROMOTE_PROTOTYPES
- if ((TREE_CODE (type) == INTEGER_TYPE
- || TREE_CODE (type) == ENUMERAL_TYPE)
+ if (PROMOTE_PROTOTYPES
+ && (TREE_CODE (type) == INTEGER_TYPE
+ || TREE_CODE (type) == ENUMERAL_TYPE)
&& (TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)))
parmval = default_conversion (parmval);
-#endif
}
result = tree_cons (NULL_TREE, parmval, result);
}
if (!(code0 == INTEGER_TYPE && code1 == INTEGER_TYPE))
resultcode = RDIV_EXPR;
else
- {
- /* Although it would be tempting to shorten always here, that
- loses on some targets, since the modulo instruction is
- undefined if the quotient can't be represented in the
- computation mode. We shorten only if unsigned or if
- dividing by something we know != -1. */
- shorten = (TREE_UNSIGNED (TREE_TYPE (orig_op0))
- || (TREE_CODE (op1) == INTEGER_CST
- && (TREE_INT_CST_LOW (op1) != -1
- || TREE_INT_CST_HIGH (op1) != -1)));
- }
+ /* Although it would be tempting to shorten always here, that
+ loses on some targets, since the modulo instruction is
+ undefined if the quotient can't be represented in the
+ computation mode. We shorten only if unsigned or if
+ dividing by something we know != -1. */
+ shorten = (TREE_UNSIGNED (TREE_TYPE (orig_op0))
+ || (TREE_CODE (op1) == INTEGER_CST
+ && ! integer_all_onesp (op1)));
common = 1;
}
break;
only if unsigned or if dividing by something we know != -1. */
shorten = (TREE_UNSIGNED (TREE_TYPE (orig_op0))
|| (TREE_CODE (op1) == INTEGER_CST
- && (TREE_INT_CST_LOW (op1) != -1
- || TREE_INT_CST_HIGH (op1) != -1)));
+ && ! integer_all_onesp (op1)));
common = 1;
}
break;
warning ("right shift count is negative");
else
{
- if (TREE_INT_CST_LOW (op1) | TREE_INT_CST_HIGH (op1))
+ if (! integer_zerop (op1))
short_shift = 1;
- if (TREE_INT_CST_HIGH (op1) != 0
- || ((unsigned HOST_WIDE_INT) TREE_INT_CST_LOW (op1)
- >= TYPE_PRECISION (type0)))
+
+ if (compare_tree_int (op1, TYPE_PRECISION (type0)) >= 0)
warning ("right shift count >= width of type");
}
}
+
/* Use the type of the value to be shifted.
This is what most traditional C compilers do. */
result_type = type0;
{
if (tree_int_cst_sgn (op1) < 0)
warning ("left shift count is negative");
- else if (TREE_INT_CST_HIGH (op1) != 0
- || ((unsigned HOST_WIDE_INT) TREE_INT_CST_LOW (op1)
- >= TYPE_PRECISION (type0)))
+
+ else if (compare_tree_int (op1, TYPE_PRECISION (type0)) >= 0)
warning ("left shift count >= width of type");
}
+
/* Use the type of the value to be shifted.
This is what most traditional C compilers do. */
result_type = type0;
{
if (tree_int_cst_sgn (op1) < 0)
warning ("shift count is negative");
- else if (TREE_INT_CST_HIGH (op1) != 0
- || ((unsigned HOST_WIDE_INT) TREE_INT_CST_LOW (op1)
- >= TYPE_PRECISION (type0)))
+ else if (compare_tree_int (op1, TYPE_PRECISION (type0)) >= 0)
warning ("shift count >= width of type");
}
+
/* Use the type of the value to be shifted.
This is what most traditional C compilers do. */
result_type = type0;
case EQ_EXPR:
case NE_EXPR:
+ if (warn_float_equal && (code0 == REAL_TYPE || code1 == REAL_TYPE))
+ warning ("comparing floating point with == or != is unsafe");
/* Result of comparison is always int,
but don't convert the args to int! */
build_type = integer_type_node;
if (comp_target_types (type0, type1))
{
result_type = common_type (type0, type1);
- if ((TYPE_SIZE (TREE_TYPE (type0)) != 0)
- != (TYPE_SIZE (TREE_TYPE (type1)) != 0))
+ if (!COMPLETE_TYPE_P (TREE_TYPE (type0))
+ != !COMPLETE_TYPE_P (TREE_TYPE (type1)))
pedwarn ("comparison of complete and incomplete pointers");
else if (pedantic
&& TREE_CODE (TREE_TYPE (type0)) == FUNCTION_TYPE)
pedwarn ("comparison between pointer and integer");
}
break;
-
+
+ case UNORDERED_EXPR:
+ case ORDERED_EXPR:
+ case UNLT_EXPR:
+ case UNLE_EXPR:
+ case UNGT_EXPR:
+ case UNGE_EXPR:
+ case UNEQ_EXPR:
+ build_type = integer_type_node;
+ if (code0 != REAL_TYPE || code1 != REAL_TYPE)
+ {
+ error ("unordered comparison on non-floating point argument");
+ return error_mark_node;
+ }
+ common = 1;
+ break;
+
default:
break;
}
if (TYPE_PRECISION (TREE_TYPE (arg0)) < TYPE_PRECISION (result_type)
/* We can shorten only if the shift count is less than the
number of bits in the smaller type size. */
- && TREE_INT_CST_HIGH (op1) == 0
- && TYPE_PRECISION (TREE_TYPE (arg0)) > TREE_INT_CST_LOW (op1)
+ && compare_tree_int (op1, TYPE_PRECISION (TREE_TYPE (arg0))) < 0
/* If arg is sign-extended and then unsigned-shifted,
we can simulate this with a signed shift in arg's type
only if the extended result is at least twice as wide
it never happens because available widths are 2**N. */
&& (!TREE_UNSIGNED (final_type)
|| unsigned_arg
- || 2 * TYPE_PRECISION (TREE_TYPE (arg0)) <= TYPE_PRECISION (result_type)))
+ || (2 * TYPE_PRECISION (TREE_TYPE (arg0))
+ <= TYPE_PRECISION (result_type))))
{
/* Do an unsigned shift if the operand was zero-extended. */
result_type
enum tree_code xresultcode = resultcode;
tree val
= shorten_compare (&xop0, &xop1, &xresult_type, &xresultcode);
+
if (val != 0)
return val;
+
op0 = xop0, op1 = xop1;
converted = 1;
resultcode = xresultcode;
{
int op0_signed = ! TREE_UNSIGNED (TREE_TYPE (orig_op0));
int op1_signed = ! TREE_UNSIGNED (TREE_TYPE (orig_op1));
-
int unsignedp0, unsignedp1;
tree primop0 = get_narrower (op0, &unsignedp0);
tree primop1 = get_narrower (op1, &unsignedp1);
- /* Avoid spurious warnings for comparison with enumerators. */
-
xop0 = orig_op0;
xop1 = orig_op1;
STRIP_TYPE_NOPS (xop0);
STRIP_TYPE_NOPS (xop1);
/* Give warnings for comparisons between signed and unsigned
- quantities that may fail. */
- /* Do the checking based on the original operand trees, so that
- casts will be considered, but default promotions won't be. */
+ quantities that may fail.
- /* Do not warn if the comparison is being done in a signed type,
+ Do the checking based on the original operand trees, so that
+ casts will be considered, but default promotions won't be.
+
+ Do not warn if the comparison is being done in a signed type,
since the signed type will only be chosen if it can represent
all the values of the unsigned type. */
if (! TREE_UNSIGNED (result_type))
/* OK */;
- /* Do not warn if both operands are unsigned. */
+ /* Do not warn if both operands are the same signedness. */
else if (op0_signed == op1_signed)
/* OK */;
- /* Do not warn if the signed quantity is an unsuffixed
- integer literal (or some static constant expression
- involving such literals) and it is non-negative. */
- else if ((op0_signed && TREE_CODE (xop0) == INTEGER_CST
- && tree_int_cst_sgn (xop0) >= 0)
- || (op1_signed && TREE_CODE (xop1) == INTEGER_CST
- && tree_int_cst_sgn (xop1) >= 0))
- /* OK */;
- /* Do not warn if the comparison is an equality operation,
- the unsigned quantity is an integral constant and it does
- not use the most significant bit of result_type. */
- else if ((resultcode == EQ_EXPR || resultcode == NE_EXPR)
- && ((op0_signed && TREE_CODE (xop1) == INTEGER_CST
- && int_fits_type_p (xop1, signed_type (result_type)))
- || (op1_signed && TREE_CODE (xop0) == INTEGER_CST
- && int_fits_type_p (xop0, signed_type (result_type)))))
- /* OK */;
else
- warning ("comparison between signed and unsigned");
+ {
+ tree sop, uop;
+
+ if (op0_signed)
+ sop = xop0, uop = xop1;
+ else
+ sop = xop1, uop = xop0;
+
+ /* Do not warn if the signed quantity is an
+ unsuffixed integer literal (or some static
+ constant expression involving such literals or a
+ conditional expression involving such literals)
+ and it is non-negative. */
+ if (tree_expr_nonnegative_p (sop))
+ /* OK */;
+ /* Do not warn if the comparison is an equality operation,
+ the unsigned quantity is an integral constant, and it
+ would fit in the result if the result were signed. */
+ else if (TREE_CODE (uop) == INTEGER_CST
+ && (resultcode == EQ_EXPR || resultcode == NE_EXPR)
+ && int_fits_type_p (uop, signed_type (result_type)))
+ /* OK */;
+ /* Do not warn if the unsigned quantity is an enumeration
+ constant and its maximum value would fit in the result
+ if the result were signed. */
+ else if (TREE_CODE (uop) == INTEGER_CST
+ && TREE_CODE (TREE_TYPE (uop)) == ENUMERAL_TYPE
+ && int_fits_type_p (TYPE_MAX_VALUE (TREE_TYPE(uop)),
+ signed_type (result_type)))
+ /* OK */;
+ else
+ warning ("comparison between signed and unsigned");
+ }
/* Warn if two unsigned values are being compared in a size
larger than their original size, and one (and only one) is the
primop1 = get_narrower (TREE_OPERAND (primop1, 0),
&unsignedp1);
- if (TREE_CODE (primop0) == INTEGER_CST
- || TREE_CODE (primop1) == INTEGER_CST)
+ if (host_integerp (primop0, 0) || host_integerp (primop1, 0))
{
tree primop;
- long constant, mask;
+ HOST_WIDE_INT constant, mask;
int unsignedp, bits;
- if (TREE_CODE (primop0) == INTEGER_CST)
+ if (host_integerp (primop0, 0))
{
primop = primop1;
unsignedp = unsignedp1;
- constant = TREE_INT_CST_LOW (primop0);
+ constant = tree_low_cst (primop0, 0);
}
else
{
primop = primop0;
unsignedp = unsignedp0;
- constant = TREE_INT_CST_LOW (primop1);
+ constant = tree_low_cst (primop1, 0);
}
bits = TYPE_PRECISION (TREE_TYPE (primop));
if (bits < TYPE_PRECISION (result_type)
- && bits < HOST_BITS_PER_LONG && unsignedp)
+ && bits < HOST_BITS_PER_WIDE_INT && unsignedp)
{
- mask = (~0L) << bits;
+ mask = (~ (HOST_WIDE_INT) 0) << bits;
if ((mask & constant) != mask)
warning ("comparison of promoted ~unsigned with constant");
}
op0 = build_binary_op (MINUS_EXPR, convert (restype, op0),
convert (restype, op1), 0);
/* This generates an error if op1 is pointer to incomplete type. */
- if (TYPE_SIZE (TREE_TYPE (TREE_TYPE (op1))) == 0)
+ if (!COMPLETE_OR_VOID_TYPE_P (TREE_TYPE (TREE_TYPE (op1))))
error ("arithmetic on pointer to an incomplete type");
/* This generates an error if op0 is pointer to incomplete type. */
register tree arg = xarg;
register tree argtype = 0;
register enum tree_code typecode = TREE_CODE (TREE_TYPE (arg));
- char *errstring = NULL;
tree val;
if (typecode == ERROR_MARK)
associativity, but won't generate any code. */
if (!(typecode == INTEGER_TYPE || typecode == REAL_TYPE
|| typecode == COMPLEX_TYPE))
- errstring = "wrong type argument to unary plus";
+ {
+ error ("wrong type argument to unary plus");
+ return error_mark_node;
+ }
else if (!noconvert)
arg = default_conversion (arg);
break;
case NEGATE_EXPR:
if (!(typecode == INTEGER_TYPE || typecode == REAL_TYPE
|| typecode == COMPLEX_TYPE))
- errstring = "wrong type argument to unary minus";
+ {
+ error ("wrong type argument to unary minus");
+ return error_mark_node;
+ }
else if (!noconvert)
arg = default_conversion (arg);
break;
arg = default_conversion (arg);
}
else if (typecode != INTEGER_TYPE)
- errstring = "wrong type argument to bit-complement";
+ {
+ error ("wrong type argument to bit-complement");
+ return error_mark_node;
+ }
else if (!noconvert)
arg = default_conversion (arg);
break;
case ABS_EXPR:
if (!(typecode == INTEGER_TYPE || typecode == REAL_TYPE
|| typecode == COMPLEX_TYPE))
- errstring = "wrong type argument to abs";
+ {
+ error ("wrong type argument to abs");
+ return error_mark_node;
+ }
else if (!noconvert)
arg = default_conversion (arg);
break;
/* Conjugating a real value is a no-op, but allow it anyway. */
if (!(typecode == INTEGER_TYPE || typecode == REAL_TYPE
|| typecode == COMPLEX_TYPE))
- errstring = "wrong type argument to conjugation";
+ {
+ error ("wrong type argument to conjugation");
+ return error_mark_node;
+ }
else if (!noconvert)
arg = default_conversion (arg);
break;
/* These will convert to a pointer. */
&& typecode != ARRAY_TYPE && typecode != FUNCTION_TYPE)
{
- errstring = "wrong type argument to unary exclamation mark";
- break;
+ error ("wrong type argument to unary exclamation mark");
+ return error_mark_node;
}
arg = truthvalue_conversion (arg);
return invert_truthvalue (arg);
if (typecode != POINTER_TYPE
&& typecode != INTEGER_TYPE && typecode != REAL_TYPE)
{
- if (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR)
- errstring ="wrong type argument to increment";
- else
- errstring ="wrong type argument to decrement";
- break;
+ error ("wrong type argument to %s",
+ code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR
+ ? "increment" : "decrement");
+ return error_mark_node;
}
{
{
/* If pointer target is an undefined struct,
we just cannot know how to do the arithmetic. */
- if (TYPE_SIZE (TREE_TYPE (result_type)) == 0)
+ if (!COMPLETE_OR_VOID_TYPE_P (TREE_TYPE (result_type)))
error ("%s of pointer to unknown structure",
- ((code == PREINCREMENT_EXPR
- || code == POSTINCREMENT_EXPR)
- ? "increment" : "decrement"));
+ code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR
+ ? "increment" : "decrement");
else if ((pedantic || warn_pointer_arith)
&& (TREE_CODE (TREE_TYPE (result_type)) == FUNCTION_TYPE
|| TREE_CODE (TREE_TYPE (result_type)) == VOID_TYPE))
pedwarn ("wrong type argument to %s",
- ((code == PREINCREMENT_EXPR
- || code == POSTINCREMENT_EXPR)
- ? "increment" : "decrement"));
+ code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR
+ ? "increment" : "decrement");
inc = c_size_in_bytes (TREE_TYPE (result_type));
}
else
/* Complain about anything else that is not a true lvalue. */
if (!lvalue_or_else (arg, ((code == PREINCREMENT_EXPR
|| code == POSTINCREMENT_EXPR)
- ? "increment" : "decrement")))
+ ? "invalid lvalue in increment"
+ : "invalid lvalue in decrement")))
return error_mark_node;
/* Report a read-only lvalue. */
;
/* Anything not already handled and not a true memory reference
is an error. */
- else if (typecode != FUNCTION_TYPE && !lvalue_or_else (arg, "unary `&'"))
+ else if (typecode != FUNCTION_TYPE
+ && !lvalue_or_else (arg, "invalid lvalue in unary `&'"))
return error_mark_node;
/* Ordinary case; arg is a COMPONENT_REF or a decl. */
argtype = TREE_TYPE (arg);
- /* If the lvalue is const or volatile,
- merge that into the type that the address will point to. */
- if (TREE_CODE_CLASS (TREE_CODE (arg)) == 'd'
- || TREE_CODE_CLASS (TREE_CODE (arg)) == 'r')
- {
- if (TREE_READONLY (arg) || TREE_THIS_VOLATILE (arg))
- argtype = c_build_type_variant (argtype,
- TREE_READONLY (arg),
- TREE_THIS_VOLATILE (arg));
- }
+
+ /* If the lvalue is const or volatile, merge that into the type
+ to which the address will point. Note that you can't get a
+ restricted pointer by taking the address of something, so we
+ only have to deal with `const' and `volatile' here. */
+ if ((DECL_P (arg) || TREE_CODE_CLASS (TREE_CODE (arg)) == 'r')
+ && (TREE_READONLY (arg) || TREE_THIS_VOLATILE (arg)))
+ argtype = c_build_type_variant (argtype,
+ TREE_READONLY (arg),
+ TREE_THIS_VOLATILE (arg));
argtype = build_pointer_type (argtype);
return error_mark_node;
}
- addr = convert (argtype, addr);
-
- if (! integer_zerop (DECL_FIELD_BITPOS (field)))
- {
- tree offset
- = size_binop (EASY_DIV_EXPR, DECL_FIELD_BITPOS (field),
- size_int (BITS_PER_UNIT));
- int flag = TREE_CONSTANT (addr);
- addr = fold (build (PLUS_EXPR, argtype,
- addr, convert (argtype, offset)));
- TREE_CONSTANT (addr) = flag;
- }
+ addr = fold (build (PLUS_EXPR, argtype,
+ convert (argtype, addr),
+ convert (argtype, byte_position (field))));
}
else
addr = build1 (code, argtype, arg);
break;
}
- if (!errstring)
- {
- if (argtype == 0)
- argtype = TREE_TYPE (arg);
- return fold (build1 (code, argtype, arg));
- }
-
- error (errstring);
- return error_mark_node;
+ if (argtype == 0)
+ argtype = TREE_TYPE (arg);
+ return fold (build1 (code, argtype, arg));
}
#if 0
otherwise, print an error message and return zero. */
int
-lvalue_or_else (ref, string)
+lvalue_or_else (ref, msgid)
tree ref;
- char *string;
+ const char *msgid;
{
int win = lvalue_p (ref);
+
if (! win)
- error ("invalid lvalue in %s", string);
+ error ("%s", msgid);
+
return win;
}
enum tree_code code;
{
if (pedantic)
- pedwarn ("ANSI C forbids use of %s expressions as lvalues",
- code == COND_EXPR ? "conditional"
- : code == COMPOUND_EXPR ? "compound" : "cast");
+ switch (code)
+ {
+ case COND_EXPR:
+ pedwarn ("ANSI C forbids use of conditional expressions as lvalues");
+ break;
+ case COMPOUND_EXPR:
+ pedwarn ("ANSI C forbids use of compound expressions as lvalues");
+ break;
+ default:
+ pedwarn ("ANSI C forbids use of cast expressions as lvalues");
+ break;
+ }
}
\f
/* Warn about storing in something that is `const'. */
void
-readonly_warning (arg, string)
+readonly_warning (arg, msgid)
tree arg;
- char *string;
+ const char *msgid;
{
- char buf[80];
- strcpy (buf, string);
-
/* Forbid assignments to iterators. */
if (TREE_CODE (arg) == VAR_DECL && ITERATOR_P (arg))
- {
- strcat (buf, " of iterator `%s'");
- pedwarn (buf, IDENTIFIER_POINTER (DECL_NAME (arg)));
- }
+ pedwarn ("%s of iterator `%s'", _(msgid),
+ IDENTIFIER_POINTER (DECL_NAME (arg)));
if (TREE_CODE (arg) == COMPONENT_REF)
{
if (TYPE_READONLY (TREE_TYPE (TREE_OPERAND (arg, 0))))
- readonly_warning (TREE_OPERAND (arg, 0), string);
+ readonly_warning (TREE_OPERAND (arg, 0), msgid);
else
- {
- strcat (buf, " of read-only member `%s'");
- pedwarn (buf, IDENTIFIER_POINTER (DECL_NAME (TREE_OPERAND (arg, 1))));
- }
+ pedwarn ("%s of read-only member `%s'", _(msgid),
+ IDENTIFIER_POINTER (DECL_NAME (TREE_OPERAND (arg, 1))));
}
else if (TREE_CODE (arg) == VAR_DECL)
- {
- strcat (buf, " of read-only variable `%s'");
- pedwarn (buf, IDENTIFIER_POINTER (DECL_NAME (arg)));
- }
+ pedwarn ("%s of read-only variable `%s'", _(msgid),
+ IDENTIFIER_POINTER (DECL_NAME (arg)));
else
- {
- pedwarn ("%s of read-only location", buf);
- }
+ pedwarn ("%s of read-only location", _(msgid));
}
\f
/* Mark EXP saying that we need to be able to take the
&& (code2 == INTEGER_TYPE || code2 == REAL_TYPE))
{
result_type = common_type (type1, type2);
+
+ /* If -Wsign-compare, warn here if type1 and type2 have
+ different signedness. We'll promote the signed to unsigned
+ and later code won't know it used to be different.
+ Do this check on the original types, so that explicit casts
+ will be considered, but default promotions won't. */
+ if ((warn_sign_compare < 0 ? extra_warnings : warn_sign_compare)
+ && !skip_evaluation)
+ {
+ int unsigned_op1 = TREE_UNSIGNED (TREE_TYPE (orig_op1));
+ int unsigned_op2 = TREE_UNSIGNED (TREE_TYPE (orig_op2));
+
+ if (unsigned_op1 ^ unsigned_op2)
+ {
+ /* Do not warn if the result type is signed, since the
+ signed type will only be chosen if it can represent
+ all the values of the unsigned type. */
+ if (! TREE_UNSIGNED (result_type))
+ /* OK */;
+ /* Do not warn if the signed quantity is an unsuffixed
+ integer literal (or some static constant expression
+ involving such literals) and it is non-negative. */
+ else if ((unsigned_op2 && tree_expr_nonnegative_p (op1))
+ || (unsigned_op1 && tree_expr_nonnegative_p (op2)))
+ /* OK */;
+ else
+ warning ("signed and unsigned type in conditional expression");
+ }
+ }
}
else if (code1 == VOID_TYPE || code2 == VOID_TYPE)
{
if (result_type != TREE_TYPE (op2))
op2 = convert_and_check (result_type, op2);
-#if 0
- if (code1 == RECORD_TYPE || code1 == UNION_TYPE)
- {
- result_type = TREE_TYPE (op1);
- if (TREE_CONSTANT (ifexp))
- return pedantic_non_lvalue (integer_zerop (ifexp) ? op2 : op1);
-
- if (TYPE_MODE (result_type) == BLKmode)
- {
- register tree tempvar
- = build_decl (VAR_DECL, NULL_TREE, result_type);
- register tree xop1 = build_modify_expr (tempvar, op1);
- register tree xop2 = build_modify_expr (tempvar, op2);
- register tree result = fold (build (COND_EXPR, result_type,
- ifexp, xop1, xop2));
-
- layout_decl (tempvar, TYPE_ALIGN (result_type));
- /* No way to handle variable-sized objects here.
- I fear that the entire handling of BLKmode conditional exprs
- needs to be redone. */
- if (TREE_CODE (DECL_SIZE (tempvar)) != INTEGER_CST)
- abort ();
- DECL_RTL (tempvar)
- = assign_stack_local (DECL_MODE (tempvar),
- (TREE_INT_CST_LOW (DECL_SIZE (tempvar))
- + BITS_PER_UNIT - 1)
- / BITS_PER_UNIT,
- 0);
-
- TREE_SIDE_EFFECTS (result)
- = TREE_SIDE_EFFECTS (ifexp) | TREE_SIDE_EFFECTS (op1)
- | TREE_SIDE_EFFECTS (op2);
- return build (COMPOUND_EXPR, result_type, result, tempvar);
- }
- }
-#endif /* 0 */
-
if (TREE_CODE (ifexp) == INTEGER_CST)
return pedantic_non_lvalue (integer_zerop (ifexp) ? op2 : op1);
if (field)
{
- char *name;
+ const char *name;
tree t;
if (pedantic)
&& TREE_CODE (type) == POINTER_TYPE
&& TREE_CODE (otype) == POINTER_TYPE)
{
- /* Go to the innermost object being pointed to. */
tree in_type = type;
tree in_otype = otype;
+ int warn = 0;
+
+ /* Check that the qualifiers on IN_TYPE are a superset of
+ the qualifiers of IN_OTYPE. The outermost level of
+ POINTER_TYPE nodes is uninteresting and we stop as soon
+ as we hit a non-POINTER_TYPE node on either type. */
+ do
+ {
+ in_otype = TREE_TYPE (in_otype);
+ in_type = TREE_TYPE (in_type);
+ warn |= (TYPE_QUALS (in_otype) & ~TYPE_QUALS (in_type));
+ }
+ while (TREE_CODE (in_type) == POINTER_TYPE
+ && TREE_CODE (in_otype) == POINTER_TYPE);
- while (TREE_CODE (in_type) == POINTER_TYPE)
- in_type = TREE_TYPE (in_type);
- while (TREE_CODE (in_otype) == POINTER_TYPE)
- in_otype = TREE_TYPE (in_otype);
-
- if (TYPE_VOLATILE (in_otype) && ! TYPE_VOLATILE (in_type))
- pedwarn ("cast discards `volatile' from pointer target type");
- if (TYPE_READONLY (in_otype) && ! TYPE_READONLY (in_type))
- pedwarn ("cast discards `const' from pointer target type");
+ if (warn)
+ /* There are qualifiers present in IN_OTYPE that are not
+ present in IN_TYPE. */
+ pedwarn ("cast discards qualifiers from pointer target type");
}
/* Warn about possible alignment problems. */
/* Handle (a, b) used as an "lvalue". */
case COMPOUND_EXPR:
pedantic_lvalue_warning (COMPOUND_EXPR);
- newrhs = build_modify_expr (TREE_OPERAND (lhs, 1),
- modifycode, rhs);
+ newrhs = build_modify_expr (TREE_OPERAND (lhs, 1), modifycode, rhs);
if (TREE_CODE (newrhs) == ERROR_MARK)
return error_mark_node;
return build (COMPOUND_EXPR, lhstype,
/* Now we have handled acceptable kinds of LHS that are not truly lvalues.
Reject anything strange now. */
- if (!lvalue_or_else (lhs, "assignment"))
+ if (!lvalue_or_else (lhs, "invalid lvalue in assignment"))
return error_mark_node;
/* Warn about storing in something that is `const'. */
/* Convert new value to destination type. */
- newrhs = convert_for_assignment (lhstype, newrhs, "assignment",
+ newrhs = convert_for_assignment (lhstype, newrhs, _("assignment"),
NULL_TREE, NULL_TREE, 0);
if (TREE_CODE (newrhs) == ERROR_MARK)
return error_mark_node;
if (olhstype == TREE_TYPE (result))
return result;
- return convert_for_assignment (olhstype, result, "assignment",
+ return convert_for_assignment (olhstype, result, _("assignment"),
NULL_TREE, NULL_TREE, 0);
}
\f
for assignments that are not allowed in C.
ERRTYPE is a string to use in error messages:
"assignment", "return", etc. If it is null, this is parameter passing
- for a function call (and different error messages are output). Otherwise,
- it may be a name stored in the spelling stack and interpreted by
- get_spelling.
+ for a function call (and different error messages are output).
FUNNAME is the name of the function being called,
as an IDENTIFIER_NODE, or null.
static tree
convert_for_assignment (type, rhs, errtype, fundecl, funname, parmnum)
tree type, rhs;
- char *errtype;
+ const char *errtype;
tree fundecl, funname;
int parmnum;
{
error ("void value not ignored as it ought to be");
return error_mark_node;
}
+ /* A type converts to a reference to it.
+ This code doesn't fully support references, it's just for the
+ special case of va_start and va_copy. */
+ if (codel == REFERENCE_TYPE
+ && comptypes (TREE_TYPE (type), TREE_TYPE (rhs)) == 1)
+ {
+ if (mark_addressable (rhs) == 0)
+ return error_mark_node;
+ rhs = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (rhs)), rhs);
+
+ /* We already know that these two types are compatible, but they
+ may not be exactly identical. In fact, `TREE_TYPE (type)' is
+ likely to be __builtin_va_list and `TREE_TYPE (rhs)' is
+ likely to be va_list, a typedef to __builtin_va_list, which
+ is different enough that it will cause problems later. */
+ if (TREE_TYPE (TREE_TYPE (rhs)) != TREE_TYPE (type))
+ rhs = build1 (NOP_EXPR, build_pointer_type (TREE_TYPE (type)), rhs);
+
+ rhs = build1 (NOP_EXPR, type, rhs);
+ return rhs;
+ }
/* Arithmetic types all interconvert, and enum is treated like int. */
- if ((codel == INTEGER_TYPE || codel == REAL_TYPE || codel == ENUMERAL_TYPE
- || codel == COMPLEX_TYPE)
- && (coder == INTEGER_TYPE || coder == REAL_TYPE || coder == ENUMERAL_TYPE
- || coder == COMPLEX_TYPE))
+ else if ((codel == INTEGER_TYPE || codel == REAL_TYPE
+ || codel == ENUMERAL_TYPE || codel == COMPLEX_TYPE)
+ && (coder == INTEGER_TYPE || coder == REAL_TYPE
+ || coder == ENUMERAL_TYPE || coder == COMPLEX_TYPE))
return convert_and_check (type, rhs);
/* Conversion to a transparent union from its member types.
|| comp_target_types (memb_type, rhstype))
{
/* If this type won't generate any warnings, use it. */
- if ((TREE_CODE (ttr) == FUNCTION_TYPE
- && TREE_CODE (ttl) == FUNCTION_TYPE)
- ? ((! TYPE_READONLY (ttl) | TYPE_READONLY (ttr))
- & (! TYPE_VOLATILE (ttl) | TYPE_VOLATILE (ttr)))
- : ((TYPE_READONLY (ttl) | ! TYPE_READONLY (ttr))
- & (TYPE_VOLATILE (ttl) | ! TYPE_VOLATILE (ttr))))
+ if (TYPE_QUALS (ttl) == TYPE_QUALS (ttr)
+ || ((TREE_CODE (ttr) == FUNCTION_TYPE
+ && TREE_CODE (ttl) == FUNCTION_TYPE)
+ ? ((TYPE_QUALS (ttl) | TYPE_QUALS (ttr))
+ == TYPE_QUALS (ttr))
+ : ((TYPE_QUALS (ttl) | TYPE_QUALS (ttr))
+ == TYPE_QUALS (ttl))))
break;
/* Keep looking for a better type, but remember this one. */
certain things, it is okay to use a const or volatile
function where an ordinary one is wanted, but not
vice-versa. */
- if (TYPE_READONLY (ttl) && ! TYPE_READONLY (ttr))
- warn_for_assignment ("%s makes `const *' function pointer from non-const",
- get_spelling (errtype), funname,
- parmnum);
- if (TYPE_VOLATILE (ttl) && ! TYPE_VOLATILE (ttr))
- warn_for_assignment ("%s makes `volatile *' function pointer from non-volatile",
- get_spelling (errtype), funname,
- parmnum);
- }
- else
- {
- if (! TYPE_READONLY (ttl) && TYPE_READONLY (ttr))
- warn_for_assignment ("%s discards `const' from pointer target type",
- get_spelling (errtype), funname,
- parmnum);
- if (! TYPE_VOLATILE (ttl) && TYPE_VOLATILE (ttr))
- warn_for_assignment ("%s discards `volatile' from pointer target type",
- get_spelling (errtype), funname,
- parmnum);
+ if (TYPE_QUALS (ttl) & ~TYPE_QUALS (ttr))
+ warn_for_assignment ("%s makes qualified function pointer from unqualified",
+ errtype, funname, parmnum);
}
+ else if (TYPE_QUALS (ttr) & ~TYPE_QUALS (ttl))
+ warn_for_assignment ("%s discards qualifiers from pointer target type",
+ errtype, funname,
+ parmnum);
}
if (pedantic && ! DECL_IN_SYSTEM_HEADER (fundecl))
}
/* Conversions among pointers */
- else if (codel == POINTER_TYPE && coder == POINTER_TYPE)
+ else if ((codel == POINTER_TYPE || codel == REFERENCE_TYPE)
+ && (coder == POINTER_TYPE || coder == REFERENCE_TYPE))
{
register tree ttl = TREE_TYPE (type);
register tree ttr = TREE_TYPE (rhstype);
&& (!integer_zerop (rhs) || TREE_CODE (rhs) == NOP_EXPR)
&& TREE_CODE (ttl) == FUNCTION_TYPE)))
warn_for_assignment ("ANSI forbids %s between function pointer and `void *'",
- get_spelling (errtype), funname, parmnum);
+ errtype, funname, parmnum);
/* Const and volatile mean something different for function types,
so the usual warnings are not appropriate. */
else if (TREE_CODE (ttr) != FUNCTION_TYPE
&& TREE_CODE (ttl) != FUNCTION_TYPE)
{
- if (! TYPE_READONLY (ttl) && TYPE_READONLY (ttr))
- warn_for_assignment ("%s discards `const' from pointer target type",
- get_spelling (errtype), funname, parmnum);
- else if (! TYPE_VOLATILE (ttl) && TYPE_VOLATILE (ttr))
- warn_for_assignment ("%s discards `volatile' from pointer target type",
- get_spelling (errtype), funname, parmnum);
+ if (TYPE_QUALS (ttr) & ~TYPE_QUALS (ttl))
+ warn_for_assignment ("%s discards qualifiers from pointer target type",
+ errtype, funname, parmnum);
/* If this is not a case of ignoring a mismatch in signedness,
no warning. */
else if (TYPE_MAIN_VARIANT (ttl) == void_type_node
/* If there is a mismatch, do warn. */
else if (pedantic)
warn_for_assignment ("pointer targets in %s differ in signedness",
- get_spelling (errtype), funname, parmnum);
+ errtype, funname, parmnum);
}
else if (TREE_CODE (ttl) == FUNCTION_TYPE
&& TREE_CODE (ttr) == FUNCTION_TYPE)
that say the function will not do certain things,
it is okay to use a const or volatile function
where an ordinary one is wanted, but not vice-versa. */
- if (TYPE_READONLY (ttl) && ! TYPE_READONLY (ttr))
- warn_for_assignment ("%s makes `const *' function pointer from non-const",
- get_spelling (errtype), funname, parmnum);
- if (TYPE_VOLATILE (ttl) && ! TYPE_VOLATILE (ttr))
- warn_for_assignment ("%s makes `volatile *' function pointer from non-volatile",
- get_spelling (errtype), funname, parmnum);
+ if (TYPE_QUALS (ttl) & ~TYPE_QUALS (ttr))
+ warn_for_assignment ("%s makes qualified function pointer from unqualified",
+ errtype, funname, parmnum);
}
}
else
warn_for_assignment ("%s from incompatible pointer type",
- get_spelling (errtype), funname, parmnum);
+ errtype, funname, parmnum);
return convert (type, rhs);
}
else if (codel == POINTER_TYPE && coder == INTEGER_TYPE)
&& integer_zerop (TREE_OPERAND (rhs, 0))))
{
warn_for_assignment ("%s makes pointer from integer without a cast",
- get_spelling (errtype), funname, parmnum);
+ errtype, funname, parmnum);
return convert (type, rhs);
}
return null_pointer_node;
else if (codel == INTEGER_TYPE && coder == POINTER_TYPE)
{
warn_for_assignment ("%s makes integer from pointer without a cast",
- get_spelling (errtype), funname, parmnum);
+ errtype, funname, parmnum);
return convert (type, rhs);
}
parmnum);
}
else
- error ("incompatible types in %s", get_spelling (errtype));
+ error ("incompatible types in %s", errtype);
return error_mark_node;
}
-/* Print a warning using MSG.
+/* Print a warning using MSGID.
It gets OPNAME as its one parameter.
If OPNAME is null, it is replaced by "passing arg ARGNUM of `FUNCTION'".
FUNCTION and ARGNUM are handled specially if we are building an
Objective-C selector. */
static void
-warn_for_assignment (msg, opname, function, argnum)
- char *msg;
- char *opname;
+warn_for_assignment (msgid, opname, function, argnum)
+ const char *msgid;
+ const char *opname;
tree function;
int argnum;
{
- static char argstring[] = "passing arg %d of `%s'";
- static char argnofun[] = "passing arg %d";
-
if (opname == 0)
{
tree selector = maybe_building_objc_message_expr ();
+ char * new_opname;
if (selector && argnum > 2)
{
if (function)
{
/* Function name is known; supply it. */
- opname = (char *) alloca (IDENTIFIER_LENGTH (function)
- + sizeof (argstring) + 25 /*%d*/ + 1);
- sprintf (opname, argstring, argnum, IDENTIFIER_POINTER (function));
+ const char *argstring = _("passing arg %d of `%s'");
+ new_opname = (char *) alloca (IDENTIFIER_LENGTH (function)
+ + strlen (argstring) + 1 + 25
+ /*%d*/ + 1);
+ sprintf (new_opname, argstring, argnum,
+ IDENTIFIER_POINTER (function));
}
else
{
- /* Function name unknown (call through ptr); just give arg number. */
- opname = (char *) alloca (sizeof (argnofun) + 25 /*%d*/ + 1);
- sprintf (opname, argnofun, argnum);
+ /* Function name unknown (call through ptr); just give arg number.*/
+ const char *argnofun = _("passing arg %d of pointer to function");
+ new_opname = (char *) alloca (strlen (argnofun) + 1 + 25 /*%d*/ + 1);
+ sprintf (new_opname, argnofun, argnum);
}
+ opname = new_opname;
}
- pedwarn (msg, opname);
+ pedwarn (msgid, opname);
}
\f
-/* Return nonzero if VALUE is a valid constant-valued expression
- for use in initializing a static variable; one that can be an
- element of a "constant" initializer.
-
- Return null_pointer_node if the value is absolute;
- if it is relocatable, return the variable that determines the relocation.
- We assume that VALUE has been folded as much as possible;
- therefore, we do not need to check for such things as
- arithmetic-combinations of integers. */
-
-tree
-initializer_constant_valid_p (value, endtype)
- tree value;
- tree endtype;
-{
- switch (TREE_CODE (value))
- {
- case CONSTRUCTOR:
- if ((TREE_CODE (TREE_TYPE (value)) == UNION_TYPE
- || TREE_CODE (TREE_TYPE (value)) == RECORD_TYPE)
- && TREE_CONSTANT (value)
- && CONSTRUCTOR_ELTS (value))
- return
- initializer_constant_valid_p (TREE_VALUE (CONSTRUCTOR_ELTS (value)),
- endtype);
-
- return TREE_STATIC (value) ? null_pointer_node : 0;
-
- case INTEGER_CST:
- case REAL_CST:
- case STRING_CST:
- case COMPLEX_CST:
- return null_pointer_node;
-
- case ADDR_EXPR:
- return TREE_OPERAND (value, 0);
-
- case NON_LVALUE_EXPR:
- return initializer_constant_valid_p (TREE_OPERAND (value, 0), endtype);
-
- case CONVERT_EXPR:
- case NOP_EXPR:
- /* Allow conversions between pointer types. */
- if (TREE_CODE (TREE_TYPE (value)) == POINTER_TYPE
- && TREE_CODE (TREE_TYPE (TREE_OPERAND (value, 0))) == POINTER_TYPE)
- return initializer_constant_valid_p (TREE_OPERAND (value, 0), endtype);
-
- /* Allow conversions between real types. */
- if (TREE_CODE (TREE_TYPE (value)) == REAL_TYPE
- && TREE_CODE (TREE_TYPE (TREE_OPERAND (value, 0))) == REAL_TYPE)
- return initializer_constant_valid_p (TREE_OPERAND (value, 0), endtype);
-
- /* Allow length-preserving conversions between integer types. */
- if (TREE_CODE (TREE_TYPE (value)) == INTEGER_TYPE
- && TREE_CODE (TREE_TYPE (TREE_OPERAND (value, 0))) == INTEGER_TYPE
- && (TYPE_PRECISION (TREE_TYPE (value))
- == TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (value, 0)))))
- return initializer_constant_valid_p (TREE_OPERAND (value, 0), endtype);
-
- /* Allow conversions between other integer types only if
- explicit value. */
- if (TREE_CODE (TREE_TYPE (value)) == INTEGER_TYPE
- && TREE_CODE (TREE_TYPE (TREE_OPERAND (value, 0))) == INTEGER_TYPE)
- {
- tree inner = initializer_constant_valid_p (TREE_OPERAND (value, 0),
- endtype);
- if (inner == null_pointer_node)
- return null_pointer_node;
- return 0;
- }
-
- /* Allow (int) &foo provided int is as wide as a pointer. */
- if (TREE_CODE (TREE_TYPE (value)) == INTEGER_TYPE
- && TREE_CODE (TREE_TYPE (TREE_OPERAND (value, 0))) == POINTER_TYPE
- && (TYPE_PRECISION (TREE_TYPE (value))
- >= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (value, 0)))))
- return initializer_constant_valid_p (TREE_OPERAND (value, 0),
- endtype);
-
- /* Likewise conversions from int to pointers, but also allow
- conversions from 0. */
- if (TREE_CODE (TREE_TYPE (value)) == POINTER_TYPE
- && TREE_CODE (TREE_TYPE (TREE_OPERAND (value, 0))) == INTEGER_TYPE)
- {
- if (integer_zerop (TREE_OPERAND (value, 0)))
- return null_pointer_node;
- else if (TYPE_PRECISION (TREE_TYPE (value))
- <= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (value, 0))))
- return initializer_constant_valid_p (TREE_OPERAND (value, 0),
- endtype);
- }
-
- /* Allow conversions to union types if the value inside is okay. */
- if (TREE_CODE (TREE_TYPE (value)) == UNION_TYPE)
- return initializer_constant_valid_p (TREE_OPERAND (value, 0),
- endtype);
- return 0;
-
- case PLUS_EXPR:
- if (TREE_CODE (endtype) == INTEGER_TYPE
- && TYPE_PRECISION (endtype) < POINTER_SIZE)
- return 0;
- {
- tree valid0 = initializer_constant_valid_p (TREE_OPERAND (value, 0),
- endtype);
- tree valid1 = initializer_constant_valid_p (TREE_OPERAND (value, 1),
- endtype);
- /* If either term is absolute, use the other terms relocation. */
- if (valid0 == null_pointer_node)
- return valid1;
- if (valid1 == null_pointer_node)
- return valid0;
- return 0;
- }
-
- case MINUS_EXPR:
- if (TREE_CODE (endtype) == INTEGER_TYPE
- && TYPE_PRECISION (endtype) < POINTER_SIZE)
- return 0;
- {
- tree valid0 = initializer_constant_valid_p (TREE_OPERAND (value, 0),
- endtype);
- tree valid1 = initializer_constant_valid_p (TREE_OPERAND (value, 1),
- endtype);
- /* Win if second argument is absolute. */
- if (valid1 == null_pointer_node)
- return valid0;
- /* Win if both arguments have the same relocation.
- Then the value is absolute. */
- if (valid0 == valid1)
- return null_pointer_node;
- return 0;
- }
-
- default:
- return 0;
- }
-}
-
/* If VALUE is a compound expr all of whose expressions are constant, then
return its value. Otherwise, return error_mark_node.
union
{
int i;
- char *s;
+ const char *s;
} u;
};
static void
push_string (string)
- char *string;
+ const char *string;
{
PUSH_SPELLING (SPELLING_STRING, string, u.s);
}
tree decl;
{
- char *string
+ const char *string
= DECL_NAME (decl) ? IDENTIFIER_POINTER (DECL_NAME (decl)) : "<anonymous>";
PUSH_SPELLING (SPELLING_MEMBER, string, u.s);
}
register char *buffer;
{
register char *d = buffer;
- register char *s;
register struct spelling *p;
for (p = spelling_base; p < spelling; p++)
}
else
{
+ register const char *s;
if (p->kind == SPELLING_MEMBER)
*d++ = '.';
for (s = p->u.s; (*d = *s++); d++)
return buffer;
}
-/* Provide a means to pass component names derived from the spelling stack. */
-
-char initialization_message;
-
-/* Interpret the spelling of the given ERRTYPE message. */
-
-static char *
-get_spelling (errtype)
- char *errtype;
-{
- static char *buffer;
- static int size = -1;
-
- if (errtype == &initialization_message)
- {
- /* Avoid counting chars */
- static char message[] = "initialization of `%s'";
- register int needed = sizeof (message) + spelling_length () + 1;
- char *temp;
-
- if (size < 0)
- buffer = (char *) xmalloc (size = needed);
- if (needed > size)
- buffer = (char *) xrealloc (buffer, size = needed);
-
- temp = (char *) alloca (needed);
- sprintf (buffer, message, print_spelling (temp));
- return buffer;
- }
-
- return errtype;
-}
-
/* Issue an error message for a bad initializer component.
- FORMAT describes the message. OFWHAT is the name for the component.
- LOCAL is a format string for formatting the insertion of the name
- into the message.
-
- If OFWHAT is null, the component name is stored on the spelling stack.
- If the component name is a null string, then LOCAL is omitted entirely. */
+ MSGID identifies the message.
+ The component name is taken from the spelling stack. */
void
-error_init (format, local, ofwhat)
- char *format, *local, *ofwhat;
+error_init (msgid)
+ const char *msgid;
{
- char *buffer;
-
- if (ofwhat == 0)
- ofwhat = print_spelling ((char *) alloca (spelling_length () + 1));
- buffer = (char *) alloca (strlen (local) + strlen (ofwhat) + 2);
+ char *ofwhat;
+ error ("%s", msgid);
+ ofwhat = print_spelling ((char *) alloca (spelling_length () + 1));
if (*ofwhat)
- sprintf (buffer, local, ofwhat);
- else
- buffer[0] = 0;
-
- error (format, buffer);
+ error ("(near initialization for `%s')", ofwhat);
}
/* Issue a pedantic warning for a bad initializer component.
- FORMAT describes the message. OFWHAT is the name for the component.
- LOCAL is a format string for formatting the insertion of the name
- into the message.
-
- If OFWHAT is null, the component name is stored on the spelling stack.
- If the component name is a null string, then LOCAL is omitted entirely. */
+ MSGID identifies the message.
+ The component name is taken from the spelling stack. */
void
-pedwarn_init (format, local, ofwhat)
- char *format, *local, *ofwhat;
+pedwarn_init (msgid)
+ const char *msgid;
{
- char *buffer;
-
- if (ofwhat == 0)
- ofwhat = print_spelling ((char *) alloca (spelling_length () + 1));
- buffer = (char *) alloca (strlen (local) + strlen (ofwhat) + 2);
+ char *ofwhat;
+ pedwarn ("%s", msgid);
+ ofwhat = print_spelling ((char *) alloca (spelling_length () + 1));
if (*ofwhat)
- sprintf (buffer, local, ofwhat);
- else
- buffer[0] = 0;
-
- pedwarn (format, buffer);
+ pedwarn ("(near initialization for `%s')", ofwhat);
}
/* Issue a warning for a bad initializer component.
- FORMAT describes the message. OFWHAT is the name for the component.
- LOCAL is a format string for formatting the insertion of the name
- into the message.
-
- If OFWHAT is null, the component name is stored on the spelling stack.
- If the component name is a null string, then LOCAL is omitted entirely. */
+ MSGID identifies the message.
+ The component name is taken from the spelling stack. */
static void
-warning_init (format, local, ofwhat)
- char *format, *local, *ofwhat;
+warning_init (msgid)
+ const char *msgid;
{
- char *buffer;
-
- if (ofwhat == 0)
- ofwhat = print_spelling ((char *) alloca (spelling_length () + 1));
- buffer = (char *) alloca (strlen (local) + strlen (ofwhat) + 2);
+ char *ofwhat;
+ warning ("%s", msgid);
+ ofwhat = print_spelling ((char *) alloca (spelling_length () + 1));
if (*ofwhat)
- sprintf (buffer, local, ofwhat);
- else
- buffer[0] = 0;
-
- warning (format, buffer);
+ warning ("(near initialization for `%s')", ofwhat);
}
\f
/* Digest the parser output INIT as an initializer for type TYPE.
enum tree_code code = TREE_CODE (type);
tree inside_init = init;
- if (init == error_mark_node)
- return init;
+ if (type == error_mark_node || init == error_mark_node)
+ return error_mark_node;
/* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue. */
/* Do not use STRIP_NOPS here. We do not want an enumerator
!= char_type_node)
&& TYPE_PRECISION (typ1) == TYPE_PRECISION (char_type_node))
{
- error_init ("char-array%s initialized from wide string",
- " `%s'", NULL);
+ error_init ("char-array initialized from wide string");
return error_mark_node;
}
if ((TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (inside_init)))
== char_type_node)
&& TYPE_PRECISION (typ1) != TYPE_PRECISION (char_type_node))
{
- error_init ("int-array%s initialized from non-wide string",
- " `%s'", NULL);
+ error_init ("int-array initialized from non-wide string");
return error_mark_node;
}
TREE_TYPE (inside_init) = type;
if (TYPE_DOMAIN (type) != 0
- && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)
- {
- register int size = TREE_INT_CST_LOW (TYPE_SIZE (type));
- size = (size + BITS_PER_UNIT - 1) / BITS_PER_UNIT;
+ && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
/* Subtract 1 (or sizeof (wchar_t))
because it's ok to ignore the terminating null char
that is counted in the length of the constant. */
- if (size < TREE_STRING_LENGTH (inside_init)
- - (TYPE_PRECISION (typ1) != TYPE_PRECISION (char_type_node)
- ? TYPE_PRECISION (wchar_type_node) / BITS_PER_UNIT
- : 1))
- pedwarn_init (
- "initializer-string for array of chars%s is too long",
- " `%s'", NULL);
- }
+ && 0 > compare_tree_int (TYPE_SIZE_UNIT (type),
+ TREE_STRING_LENGTH (inside_init)
+ - ((TYPE_PRECISION (typ1)
+ != TYPE_PRECISION (char_type_node))
+ ? (TYPE_PRECISION (wchar_type_node)
+ / BITS_PER_UNIT)
+ : 1)))
+ pedwarn_init ("initializer-string for array of chars is too long");
+
return inside_init;
}
}
else if (code == ARRAY_TYPE && TREE_CODE (inside_init) != STRING_CST
&& TREE_CODE (inside_init) != CONSTRUCTOR)
{
- error_init ("array%s initialized from non-constant array expression",
- " `%s'", NULL);
+ error_init ("array initialized from non-constant array expression");
return error_mark_node;
}
= valid_compound_expr_initializer (inside_init,
TREE_TYPE (inside_init));
if (inside_init == error_mark_node)
- error_init ("initializer element%s is not constant",
- " for `%s'", NULL);
+ error_init ("initializer element is not constant");
else
- pedwarn_init ("initializer element%s is not constant",
- " for `%s'", NULL);
+ pedwarn_init ("initializer element is not constant");
if (flag_pedantic_errors)
inside_init = error_mark_node;
}
else if (require_constant && ! TREE_CONSTANT (inside_init))
{
- error_init ("initializer element%s is not constant",
- " for `%s'", NULL);
+ error_init ("initializer element is not constant");
inside_init = error_mark_node;
}
else if (require_constant
&& initializer_constant_valid_p (inside_init, TREE_TYPE (inside_init)) == 0)
{
- error_init ("initializer element%s is not computable at load time",
- " for `%s'", NULL);
+ error_init ("initializer element is not computable at load time");
inside_init = error_mark_node;
}
for arrays and functions. We must not call it in the
case where inside_init is a null pointer constant. */
inside_init
- = convert_for_assignment (type, init, "initialization",
+ = convert_for_assignment (type, init, _("initialization"),
NULL_TREE, NULL_TREE, 0);
if (require_constant && ! TREE_CONSTANT (inside_init))
{
- error_init ("initializer element%s is not constant",
- " for `%s'", NULL);
+ error_init ("initializer element is not constant");
inside_init = error_mark_node;
}
else if (require_constant
&& initializer_constant_valid_p (inside_init, TREE_TYPE (inside_init)) == 0)
{
- error_init ("initializer element%s is not computable at load time",
- " for `%s'", NULL);
+ error_init ("initializer element is not computable at load time");
inside_init = error_mark_node;
}
/* Come here only for records and arrays. */
- if (TYPE_SIZE (type) && TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
+ if (COMPLETE_TYPE_P (type) && TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
{
- error_init ("variable-sized object%s may not be initialized",
- " `%s'", NULL);
+ error_init ("variable-sized object may not be initialized");
return error_mark_node;
}
type = TREE_TYPE (TYPE_FIELDS (type));
else
{
- error_init ("invalid initializer%s", " for `%s'", NULL);
+ error_init ("invalid initializer");
return error_mark_node;
}
}
else
return error_mark_node;
}
- error_init ("invalid initializer%s", " for `%s'", NULL);
+ error_init ("invalid initializer");
return error_mark_node;
}
\f
static tree constructor_fields;
/* For an ARRAY_TYPE, this is the specified index
- at which to store the next element we get.
- This is a special INTEGER_CST node that we modify in place. */
+ at which to store the next element we get. */
static tree constructor_index;
/* For an ARRAY_TYPE, this is the end index of the range
static tree constructor_unfilled_fields;
/* For an ARRAY_TYPE, this is the index of the first element
- not yet written out.
- This is a special INTEGER_CST node that we modify in place. */
+ not yet written out. */
static tree constructor_unfilled_index;
/* In a RECORD_TYPE, the byte index of the next consecutive field.
- This is so we can generate gaps between fields, when appropriate.
- This is a special INTEGER_CST node that we modify in place. */
+ This is so we can generate gaps between fields, when appropriate. */
static tree constructor_bit_index;
/* If we are saving up the elements rather than allocating them,
/* Tree of pending elements at this constructor level.
These are elements encountered out of order
which belong at places we haven't reached yet in actually
- writing the output. */
+ writing the output.
+ Will never hold tree nodes across GC runs. */
static struct init_node *constructor_pending_elts;
/* The SPELLING_DEPTH of this constructor. */
tree asmspec_tree;
int top_level;
{
- char *locus;
+ const char *locus;
struct initializer_stack *p
= (struct initializer_stack *) xmalloc (sizeof (struct initializer_stack));
char *asmspec = 0;
while (constructor_fields != 0 && DECL_C_BIT_FIELD (constructor_fields)
&& DECL_NAME (constructor_fields) == 0)
constructor_fields = TREE_CHAIN (constructor_fields);
+
constructor_unfilled_fields = constructor_fields;
- constructor_bit_index = copy_node (integer_zero_node);
- TREE_TYPE (constructor_bit_index) = sbitsizetype;
+ constructor_bit_index = bitsize_zero_node;
}
else if (TREE_CODE (constructor_type) == ARRAY_TYPE)
{
constructor_max_index
= TYPE_MAX_VALUE (TYPE_DOMAIN (constructor_type));
constructor_index
- = copy_node (TYPE_MIN_VALUE (TYPE_DOMAIN (constructor_type)));
+ = convert (bitsizetype,
+ TYPE_MIN_VALUE (TYPE_DOMAIN (constructor_type)));
}
else
- constructor_index = copy_node (integer_zero_node);
- constructor_unfilled_index = copy_node (constructor_index);
+ constructor_index = bitsize_zero_node;
+
+ constructor_unfilled_index = constructor_index;
}
else
{
if (constructor_incremental)
{
- int momentary = suspend_momentary ();
- push_obstacks_nochange ();
- if (TREE_PERMANENT (constructor_decl))
- end_temporary_allocation ();
make_decl_rtl (constructor_decl, constructor_asmspec,
constructor_top_level);
assemble_variable (constructor_decl, constructor_top_level, 0, 1);
- pop_obstacks ();
- resume_momentary (momentary);
- }
- if (constructor_incremental)
- {
defer_addressed_constants ();
constructor_subconstants_deferred = 1;
}
{
/* Advance to offset of this element. */
if (! tree_int_cst_equal (constructor_bit_index,
- DECL_FIELD_BITPOS (constructor_fields)))
- {
- /* By using unsigned arithmetic, the result will be correct even
- in case of overflows, if BITS_PER_UNIT is a power of two. */
- unsigned next = (TREE_INT_CST_LOW
- (DECL_FIELD_BITPOS (constructor_fields))
- / (unsigned)BITS_PER_UNIT);
- unsigned here = (TREE_INT_CST_LOW (constructor_bit_index)
- / (unsigned)BITS_PER_UNIT);
-
- assemble_zeros ((next - here)
- * (unsigned)BITS_PER_UNIT
- / (unsigned)BITS_PER_UNIT);
- }
+ bit_position (constructor_fields)))
+ assemble_zeros
+ (tree_low_cst
+ (size_binop (TRUNC_DIV_EXPR,
+ size_binop (MINUS_EXPR,
+ bit_position (constructor_fields),
+ constructor_bit_index),
+ bitsize_unit_node),
+ 1));
+
/* Indicate that we have now filled the structure up to the current
field. */
constructor_unfilled_fields = constructor_fields;
else if (TREE_CODE (constructor_type) == ARRAY_TYPE)
{
constructor_type = TREE_TYPE (constructor_type);
- push_array_bounds (TREE_INT_CST_LOW (constructor_index));
+ push_array_bounds (tree_low_cst (constructor_index, 0));
constructor_depth++;
if (! tree_int_cst_equal (constructor_index, constructor_unfilled_index)
|| constructor_range_end != 0)
if (constructor_type == 0)
{
- error_init ("extra brace group at end of initializer%s",
- " for `%s'", NULL);
+ error_init ("extra brace group at end of initializer");
constructor_fields = 0;
constructor_unfilled_fields = 0;
return;
if (implicit && warn_missing_braces && !missing_braces_mentioned)
{
missing_braces_mentioned = 1;
- warning_init ("missing braces around initializer%s", " for `%s'", NULL);
+ warning_init ("missing braces around initializer");
}
if (TREE_CODE (constructor_type) == RECORD_TYPE
while (constructor_fields != 0 && DECL_C_BIT_FIELD (constructor_fields)
&& DECL_NAME (constructor_fields) == 0)
constructor_fields = TREE_CHAIN (constructor_fields);
+
constructor_unfilled_fields = constructor_fields;
- constructor_bit_index = copy_node (integer_zero_node);
- TREE_TYPE (constructor_bit_index) = sbitsizetype;
+ constructor_bit_index = bitsize_zero_node;
}
else if (TREE_CODE (constructor_type) == ARRAY_TYPE)
{
constructor_max_index
= TYPE_MAX_VALUE (TYPE_DOMAIN (constructor_type));
constructor_index
- = copy_node (TYPE_MIN_VALUE (TYPE_DOMAIN (constructor_type)));
+ = convert (bitsizetype,
+ TYPE_MIN_VALUE
+ (TYPE_DOMAIN (constructor_type)));
}
else
- constructor_index = copy_node (integer_zero_node);
- constructor_unfilled_index = copy_node (constructor_index);
+ constructor_index = bitsize_zero_node;
+
+ constructor_unfilled_index = constructor_index;
}
else
{
- warning_init ("braces around scalar initializer%s", " for `%s'", NULL);
+ warning_init ("braces around scalar initializer");
constructor_fields = constructor_type;
constructor_unfilled_fields = constructor_type;
}
for (tail = TYPE_FIELDS (type); tail;
tail = TREE_CHAIN (tail))
{
- if (DECL_C_BIT_FIELD (tail)
- /* This catches cases like `int foo : 8;'. */
- || DECL_MODE (tail) != TYPE_MODE (TREE_TYPE (tail)))
+ if (DECL_C_BIT_FIELD (tail))
{
constructor_incremental = 0;
break;
}
}
+ else if (TREE_CODE (type) == UNION_TYPE)
+ {
+ tree tail = TYPE_FIELDS (type);
+ if (tail && DECL_C_BIT_FIELD (tail))
+ /* We also use the nonincremental algorithm for initiliazation
+ of unions whose first member is a bitfield, becuase the
+ incremental algorithm has no code for dealing with
+ bitfields. */
+ constructor_incremental = 0;
+ }
+
else if (TREE_CODE (type) == ARRAY_TYPE)
check_init_type_bitfields (TREE_TYPE (type));
}
int implicit;
{
struct constructor_stack *p;
- int size = 0;
+ HOST_WIDE_INT size = 0;
tree constructor = 0;
if (implicit == 0)
&& constructor_unfilled_fields)
{
push_member_name (constructor_unfilled_fields);
- warning_init ("missing initializer%s", " for `%s'", NULL);
+ warning_init ("missing initializer");
RESTORE_SPELLING_DEPTH (constructor_depth);
}
&& (TREE_CODE (constructor_type) == ARRAY_TYPE
? integer_zerop (constructor_unfilled_index)
: constructor_unfilled_fields == TYPE_FIELDS (constructor_type)))
- pedwarn_init ("empty braces in initializer%s", " for `%s'", NULL);
+ pedwarn_init ("empty braces in initializer");
#endif
/* Pad out the end of the structure. */
if (TREE_CODE (constructor_type) == ARRAY_TYPE
&& TYPE_DOMAIN (constructor_type) == 0)
{
- int failure;
- int momentary_p;
-
- push_obstacks_nochange ();
- if (TREE_PERMANENT (constructor_type))
- end_temporary_allocation ();
-
- momentary_p = suspend_momentary ();
-
/* We shouldn't have an incomplete array type within
some other type. */
if (constructor_stack->next)
abort ();
- failure
- = complete_array_type (constructor_type,
- constructor, 0);
- if (failure)
+ if (complete_array_type (constructor_type, constructor, 0))
abort ();
size = int_size_in_bytes (constructor_type);
- resume_momentary (momentary_p);
- pop_obstacks ();
}
output_constant (constructor, size);
the element, after verifying there is just one. */
if (constructor_elements == 0)
{
- error_init ("empty scalar initializer%s",
- " for `%s'", NULL);
+ error_init ("empty scalar initializer");
constructor = error_mark_node;
}
else if (TREE_CHAIN (constructor_elements) != 0)
{
- error_init ("extra elements in scalar initializer%s",
- " for `%s'", NULL);
+ error_init ("extra elements in scalar initializer");
constructor = TREE_VALUE (constructor_elements);
}
else
constructor = error_mark_node;
else
{
- int momentary = suspend_momentary ();
-
constructor = build (CONSTRUCTOR, constructor_type, NULL_TREE,
nreverse (constructor_elements));
if (constructor_constant)
TREE_CONSTANT (constructor) = 1;
if (constructor_constant && constructor_simple)
TREE_STATIC (constructor) = 1;
-
- resume_momentary (momentary);
}
}
else
{
tree filled;
- int momentary = suspend_momentary ();
if (TREE_CODE (constructor_type) == RECORD_TYPE
|| TREE_CODE (constructor_type) == UNION_TYPE)
- {
- /* Find the offset of the end of that field. */
- filled = size_binop (CEIL_DIV_EXPR,
- constructor_bit_index,
- size_int (BITS_PER_UNIT));
- }
+ /* Find the offset of the end of that field. */
+ filled = size_binop (CEIL_DIV_EXPR, constructor_bit_index,
+ bitsize_unit_node);
+
else if (TREE_CODE (constructor_type) == ARRAY_TYPE)
{
/* If initializing an array of unknown size,
&& TYPE_DOMAIN (constructor_type) == 0)
{
tree maxindex
- = size_binop (MINUS_EXPR,
- constructor_unfilled_index,
- integer_one_node);
-
- push_obstacks_nochange ();
- if (TREE_PERMANENT (constructor_type))
- end_temporary_allocation ();
- maxindex = copy_node (maxindex);
+ = copy_node (size_diffop (constructor_unfilled_index,
+ bitsize_one_node));
+
TYPE_DOMAIN (constructor_type) = build_index_type (maxindex);
TREE_TYPE (maxindex) = TYPE_DOMAIN (constructor_type);
in the array, because we start counting at zero. Therefore,
warn only if the value is less than zero. */
if (pedantic
- && (tree_int_cst_sgn (TYPE_MAX_VALUE (TYPE_DOMAIN (constructor_type)))
+ && (tree_int_cst_sgn
+ (TYPE_MAX_VALUE (TYPE_DOMAIN (constructor_type)))
< 0))
error_with_decl (constructor_decl,
"zero or negative array size `%s'");
+
layout_type (constructor_type);
size = int_size_in_bytes (constructor_type);
- pop_obstacks ();
}
- filled = size_binop (MULT_EXPR, constructor_unfilled_index,
- size_in_bytes (TREE_TYPE (constructor_type)));
+ filled
+ = size_binop (MULT_EXPR, constructor_unfilled_index,
+ convert (bitsizetype,
+ TYPE_SIZE_UNIT
+ (TREE_TYPE (constructor_type))));
}
else
filled = 0;
if (filled != 0)
- assemble_zeros (size - TREE_INT_CST_LOW (filled));
-
- resume_momentary (momentary);
+ assemble_zeros (size - tree_low_cst (filled, 1));
}
|| TREE_CODE (first) == NON_LVALUE_EXPR)
&& (TYPE_MODE (TREE_TYPE (first))
== TYPE_MODE (TREE_TYPE (TREE_OPERAND (first, 0)))))
- (first) = TREE_OPERAND (first, 0);
+ first = TREE_OPERAND (first, 0);
+
if (last)
while ((TREE_CODE (last) == NOP_EXPR
|| TREE_CODE (last) == CONVERT_EXPR
|| TREE_CODE (last) == NON_LVALUE_EXPR)
&& (TYPE_MODE (TREE_TYPE (last))
== TYPE_MODE (TREE_TYPE (TREE_OPERAND (last, 0)))))
- (last) = TREE_OPERAND (last, 0);
+ last = TREE_OPERAND (last, 0);
if (TREE_CODE (first) != INTEGER_CST)
- error_init ("nonconstant array index in initializer%s", " for `%s'", NULL);
+ error_init ("nonconstant array index in initializer");
else if (last != 0 && TREE_CODE (last) != INTEGER_CST)
- error_init ("nonconstant array index in initializer%s", " for `%s'", NULL);
+ error_init ("nonconstant array index in initializer");
else if (! constructor_unfilled_index)
- error_init ("array index in non-array initializer%s", " for `%s'", NULL);
+ error_init ("array index in non-array initializer");
else if (tree_int_cst_lt (first, constructor_unfilled_index))
- error_init ("duplicate array index in initializer%s", " for `%s'", NULL);
+ error_init ("duplicate array index in initializer");
else
{
- TREE_INT_CST_LOW (constructor_index) = TREE_INT_CST_LOW (first);
- TREE_INT_CST_HIGH (constructor_index) = TREE_INT_CST_HIGH (first);
+ constructor_index = convert (bitsizetype, first);
if (last != 0 && tree_int_cst_lt (last, first))
- error_init ("empty index range in initializer%s", " for `%s'", NULL);
+ error_init ("empty index range in initializer");
else
{
if (pedantic)
pedwarn ("ANSI C forbids specifying element to initialize");
- constructor_range_end = last;
+
+ constructor_range_end = last ? convert (bitsizetype, last) : 0;
}
}
}
p = *q;
if (tree_int_cst_lt (purpose, p->purpose))
q = &p->left;
- else if (tree_int_cst_lt (p->purpose, purpose))
+ else if (p->purpose != purpose)
q = &p->right;
else
abort ();
while (*q != NULL)
{
p = *q;
- if (tree_int_cst_lt (DECL_FIELD_BITPOS (purpose),
- DECL_FIELD_BITPOS (p->purpose)))
+ if (tree_int_cst_lt (bit_position (purpose),
+ bit_position (p->purpose)))
q = &p->left;
- else if (tree_int_cst_lt (DECL_FIELD_BITPOS (p->purpose),
- DECL_FIELD_BITPOS (purpose)))
+ else if (p->purpose != purpose)
q = &p->right;
else
abort ();
}
}
- r = (struct init_node *) oballoc (sizeof (struct init_node));
+ r = (struct init_node *) ggc_alloc_obj (sizeof (struct init_node), 0);
r->purpose = purpose;
r->value = value;
{
while (p)
{
- if (tree_int_cst_equal (field, p->purpose))
+ if (field == p->purpose)
return 1;
else if (tree_int_cst_lt (field, p->purpose))
p = p->left;
{
if (field == p->purpose)
return 1;
- else if (tree_int_cst_lt (DECL_FIELD_BITPOS (field),
- DECL_FIELD_BITPOS (p->purpose)))
+ else if (tree_int_cst_lt (bit_position (field),
+ bit_position (p->purpose)))
p = p->left;
else
p = p->right;
if (require_constant_value && ! TREE_CONSTANT (value))
{
- error_init ("initializer element%s is not constant",
- " for `%s'", NULL);
+ error_init ("initializer element is not constant");
value = error_mark_node;
}
else if (require_constant_elements
&& initializer_constant_valid_p (value, TREE_TYPE (value)) == 0)
{
- error_init ("initializer element%s is not computable at load time",
- " for `%s'", NULL);
+ error_init ("initializer element is not computable at load time");
value = error_mark_node;
}
{
if (pending_init_member (field))
{
- error_init ("duplicate initializer%s", " for `%s'", NULL);
+ error_init ("duplicate initializer");
duplicate = 1;
}
}
/* If this element doesn't come next in sequence,
put it on constructor_pending_elts. */
if (TREE_CODE (constructor_type) == ARRAY_TYPE
- && !tree_int_cst_equal (field, constructor_unfilled_index))
+ && ! tree_int_cst_equal (field, constructor_unfilled_index))
{
if (! duplicate)
- /* The copy_node is needed in case field is actually
- constructor_index, which is modified in place. */
- add_pending_init (copy_node (field),
+ add_pending_init (field,
digest_init (type, value, require_constant_value,
require_constant_elements));
}
{
/* Structure elements may require alignment.
Do this, if necessary. */
- if (TREE_CODE (constructor_type) == RECORD_TYPE)
- {
- /* Advance to offset of this element. */
- if (! tree_int_cst_equal (constructor_bit_index,
- DECL_FIELD_BITPOS (field)))
- {
- /* By using unsigned arithmetic, the result will be
- correct even in case of overflows, if BITS_PER_UNIT
- is a power of two. */
- unsigned next = (TREE_INT_CST_LOW
- (DECL_FIELD_BITPOS (field))
- / (unsigned)BITS_PER_UNIT);
- unsigned here = (TREE_INT_CST_LOW
- (constructor_bit_index)
- / (unsigned)BITS_PER_UNIT);
-
- assemble_zeros ((next - here)
- * (unsigned)BITS_PER_UNIT
- / (unsigned)BITS_PER_UNIT);
- }
- }
+ if (TREE_CODE (constructor_type) == RECORD_TYPE
+ && ! tree_int_cst_equal (constructor_bit_index,
+ bit_position (field)))
+ /* Advance to offset of this element. */
+ assemble_zeros
+ (tree_low_cst
+ (size_binop (TRUNC_DIV_EXPR,
+ size_binop (MINUS_EXPR, bit_position (field),
+ constructor_bit_index),
+ bitsize_unit_node),
+ 0));
+
output_constant (digest_init (type, value,
require_constant_value,
require_constant_elements),
keep track of end position of last field. */
if (TREE_CODE (constructor_type) == RECORD_TYPE
|| TREE_CODE (constructor_type) == UNION_TYPE)
- {
- tree temp = size_binop (PLUS_EXPR, DECL_FIELD_BITPOS (field),
- DECL_SIZE (field));
- TREE_INT_CST_LOW (constructor_bit_index)
- = TREE_INT_CST_LOW (temp);
- TREE_INT_CST_HIGH (constructor_bit_index)
- = TREE_INT_CST_HIGH (temp);
- }
+ constructor_bit_index
+ = size_binop (PLUS_EXPR, bit_position (field),
+ DECL_SIZE (field));
}
}
/* Advance the variable that indicates sequential elements output. */
if (TREE_CODE (constructor_type) == ARRAY_TYPE)
+ constructor_unfilled_index
+ = size_binop (PLUS_EXPR, constructor_unfilled_index,
+ bitsize_one_node);
+ else if (TREE_CODE (constructor_type) == RECORD_TYPE)
{
- tree tem = size_binop (PLUS_EXPR, constructor_unfilled_index,
- integer_one_node);
- TREE_INT_CST_LOW (constructor_unfilled_index)
- = TREE_INT_CST_LOW (tem);
- TREE_INT_CST_HIGH (constructor_unfilled_index)
- = TREE_INT_CST_HIGH (tem);
+ constructor_unfilled_fields
+ = TREE_CHAIN (constructor_unfilled_fields);
+
+ /* Skip any nameless bit fields. */
+ while (constructor_unfilled_fields != 0
+ && DECL_C_BIT_FIELD (constructor_unfilled_fields)
+ && DECL_NAME (constructor_unfilled_fields) == 0)
+ constructor_unfilled_fields =
+ TREE_CHAIN (constructor_unfilled_fields);
}
- else if (TREE_CODE (constructor_type) == RECORD_TYPE)
- constructor_unfilled_fields = TREE_CHAIN (constructor_unfilled_fields);
else if (TREE_CODE (constructor_type) == UNION_TYPE)
constructor_unfilled_fields = 0;
constructor_unfilled_fields,
0);
}
- else if (tree_int_cst_lt (DECL_FIELD_BITPOS (constructor_unfilled_fields),
- DECL_FIELD_BITPOS (elt->purpose)))
+ else if (tree_int_cst_lt (bit_position (constructor_unfilled_fields),
+ bit_position (elt->purpose)))
{
/* Advance to the next smaller node. */
if (elt->left)
elt = elt->parent;
elt = elt->parent;
if (elt
- && tree_int_cst_lt (DECL_FIELD_BITPOS (constructor_unfilled_fields),
- DECL_FIELD_BITPOS (elt->purpose)))
+ && (tree_int_cst_lt
+ (bit_position (constructor_unfilled_fields),
+ bit_position (elt->purpose))))
{
next = elt->purpose;
break;
if (constructor_incremental)
{
tree filled;
- tree nextpos_tree = size_int (0);
+ tree nextpos_tree = bitsize_zero_node;
if (TREE_CODE (constructor_type) == RECORD_TYPE
|| TREE_CODE (constructor_type) == UNION_TYPE)
{
tree tail;
+
/* Find the last field written out, if any. */
for (tail = TYPE_FIELDS (constructor_type); tail;
tail = TREE_CHAIN (tail))
if (tail)
/* Find the offset of the end of that field. */
filled = size_binop (CEIL_DIV_EXPR,
- size_binop (PLUS_EXPR,
- DECL_FIELD_BITPOS (tail),
+ size_binop (PLUS_EXPR, bit_position (tail),
DECL_SIZE (tail)),
- size_int (BITS_PER_UNIT));
+ bitsize_unit_node);
else
- filled = size_int (0);
-
- nextpos_tree = size_binop (CEIL_DIV_EXPR,
- DECL_FIELD_BITPOS (next),
- size_int (BITS_PER_UNIT));
+ filled = bitsize_zero_node;
- TREE_INT_CST_HIGH (constructor_bit_index)
- = TREE_INT_CST_HIGH (DECL_FIELD_BITPOS (next));
- TREE_INT_CST_LOW (constructor_bit_index)
- = TREE_INT_CST_LOW (DECL_FIELD_BITPOS (next));
+ nextpos_tree = convert (bitsizetype, byte_position (next));
+ constructor_bit_index = bit_position (next);
constructor_unfilled_fields = next;
}
else if (TREE_CODE (constructor_type) == ARRAY_TYPE)
{
- filled = size_binop (MULT_EXPR, constructor_unfilled_index,
- size_in_bytes (TREE_TYPE (constructor_type)));
+ filled
+ = size_binop (MULT_EXPR, constructor_unfilled_index,
+ convert (bitsizetype,
+ TYPE_SIZE_UNIT
+ (TREE_TYPE (constructor_type))));
nextpos_tree
= size_binop (MULT_EXPR, next,
- size_in_bytes (TREE_TYPE (constructor_type)));
- TREE_INT_CST_LOW (constructor_unfilled_index)
- = TREE_INT_CST_LOW (next);
- TREE_INT_CST_HIGH (constructor_unfilled_index)
- = TREE_INT_CST_HIGH (next);
+ convert (bitsizetype, TYPE_SIZE_UNIT
+ (TREE_TYPE (constructor_type))));
+ constructor_unfilled_index = next;
}
else
filled = 0;
if (filled)
- {
- int nextpos = TREE_INT_CST_LOW (nextpos_tree);
-
- assemble_zeros (nextpos - TREE_INT_CST_LOW (filled));
- }
+ assemble_zeros (tree_low_cst (size_diffop (nextpos_tree, filled), 1));
}
else
{
|| TREE_CODE (constructor_type) == UNION_TYPE)
constructor_unfilled_fields = next;
else if (TREE_CODE (constructor_type) == ARRAY_TYPE)
- {
- TREE_INT_CST_LOW (constructor_unfilled_index)
- = TREE_INT_CST_LOW (next);
- TREE_INT_CST_HIGH (constructor_unfilled_index)
- = TREE_INT_CST_HIGH (next);
- }
+ constructor_unfilled_index = next;
}
/* ELT now points to the node in the pending tree with the next
&& TREE_CODE (TREE_TYPE (constructor_type)) == INTEGER_TYPE
&& integer_zerop (constructor_unfilled_index))
{
+ if (constructor_stack->replacement_value)
+ error_init ("excess elements in char array initializer");
constructor_stack->replacement_value = value;
return;
}
if (constructor_stack->replacement_value != 0)
{
- error_init ("excess elements in struct initializer%s",
- " after `%s'", NULL_PTR);
+ error_init ("excess elements in struct initializer");
return;
}
if (constructor_fields == 0)
{
- pedwarn_init ("excess elements in struct initializer%s",
- " after `%s'", NULL_PTR);
+ pedwarn_init ("excess elements in struct initializer");
break;
}
directly output as a constructor. */
{
/* For a record, keep track of end position of last field. */
- tree temp = size_binop (PLUS_EXPR,
- DECL_FIELD_BITPOS (constructor_fields),
- DECL_SIZE (constructor_fields));
- TREE_INT_CST_LOW (constructor_bit_index)
- = TREE_INT_CST_LOW (temp);
- TREE_INT_CST_HIGH (constructor_bit_index)
- = TREE_INT_CST_HIGH (temp);
+ constructor_bit_index
+ = size_binop (PLUS_EXPR,
+ bit_position (constructor_fields),
+ DECL_SIZE (constructor_fields));
constructor_unfilled_fields = TREE_CHAIN (constructor_fields);
+ /* Skip any nameless bit fields. */
+ while (constructor_unfilled_fields != 0
+ && DECL_C_BIT_FIELD (constructor_unfilled_fields)
+ && DECL_NAME (constructor_unfilled_fields) == 0)
+ constructor_unfilled_fields =
+ TREE_CHAIN (constructor_unfilled_fields);
}
constructor_fields = TREE_CHAIN (constructor_fields);
if (constructor_fields == 0)
{
- pedwarn_init ("excess elements in union initializer%s",
- " after `%s'", NULL_PTR);
+ pedwarn_init ("excess elements in union initializer");
break;
}
/* Do the bookkeeping for an element that was
directly output as a constructor. */
{
- TREE_INT_CST_LOW (constructor_bit_index)
- = TREE_INT_CST_LOW (DECL_SIZE (constructor_fields));
- TREE_INT_CST_HIGH (constructor_bit_index)
- = TREE_INT_CST_HIGH (DECL_SIZE (constructor_fields));
-
+ constructor_bit_index = DECL_SIZE (constructor_fields);
constructor_unfilled_fields = TREE_CHAIN (constructor_fields);
}
if (constructor_max_index != 0
&& tree_int_cst_lt (constructor_max_index, constructor_index))
{
- pedwarn_init ("excess elements in array initializer%s",
- " after `%s'", NULL_PTR);
+ pedwarn_init ("excess elements in array initializer");
break;
}
&& tree_int_cst_lt (constructor_max_index,
constructor_range_end))
{
- pedwarn_init ("excess elements in array initializer%s",
- " after `%s'", NULL_PTR);
- TREE_INT_CST_HIGH (constructor_range_end)
- = TREE_INT_CST_HIGH (constructor_max_index);
- TREE_INT_CST_LOW (constructor_range_end)
- = TREE_INT_CST_LOW (constructor_max_index);
+ pedwarn_init ("excess elements in array initializer");
+ constructor_range_end = constructor_max_index;
}
value = save_expr (value);
If there is a range, repeat it till we advance past the range. */
do
{
- tree tem;
-
if (value)
{
- push_array_bounds (TREE_INT_CST_LOW (constructor_index));
+ push_array_bounds (tree_low_cst (constructor_index, 0));
output_init_element (value, elttype, constructor_index, 1);
RESTORE_SPELLING_DEPTH (constructor_depth);
}
- tem = size_binop (PLUS_EXPR, constructor_index,
- integer_one_node);
- TREE_INT_CST_LOW (constructor_index) = TREE_INT_CST_LOW (tem);
- TREE_INT_CST_HIGH (constructor_index) = TREE_INT_CST_HIGH (tem);
+ constructor_index
+ = size_binop (PLUS_EXPR, constructor_index, bitsize_one_node);
- if (!value)
+ if (! value)
/* If we are doing the bookkeeping for an element that was
- directly output as a constructor,
- we must update constructor_unfilled_index. */
- {
- TREE_INT_CST_LOW (constructor_unfilled_index)
- = TREE_INT_CST_LOW (constructor_index);
- TREE_INT_CST_HIGH (constructor_unfilled_index)
- = TREE_INT_CST_HIGH (constructor_index);
- }
+ directly output as a constructor, we must update
+ constructor_unfilled_index. */
+ constructor_unfilled_index = constructor_index;
}
while (! (constructor_range_end == 0
|| tree_int_cst_lt (constructor_range_end,
for a scalar variable. */
if (constructor_fields == 0)
{
- pedwarn_init ("excess elements in scalar initializer%s",
- " after `%s'", NULL_PTR);
+ pedwarn_init ("excess elements in scalar initializer");
break;
}
constructor_fields = 0;
break;
}
-
- /* If the (lexically) previous elments are not now saved,
- we can discard the storage for them. */
- if (constructor_incremental && constructor_pending_elts == 0 && value != 0
- && constructor_stack == 0)
- clear_momentary ();
}
\f
/* Expand an ASM statement with operands, handling output operands
/* Record the contents of OUTPUTS before it is modified. */
for (i = 0, tail = outputs; tail; tail = TREE_CHAIN (tail), i++)
- o[i] = TREE_VALUE (tail);
+ {
+ tree output = TREE_VALUE (tail);
+
+ /* We can remove conversions that just change the type, not the mode. */
+ STRIP_NOPS (output);
+ o[i] = output;
+
+ /* Allow conversions as LHS here. build_modify_expr as called below
+ will do the right thing with them. */
+ while (TREE_CODE (output) == NOP_EXPR
+ || TREE_CODE (output) == CONVERT_EXPR
+ || TREE_CODE (output) == FLOAT_EXPR
+ || TREE_CODE (output) == FIX_TRUNC_EXPR
+ || TREE_CODE (output) == FIX_FLOOR_EXPR
+ || TREE_CODE (output) == FIX_ROUND_EXPR
+ || TREE_CODE (output) == FIX_CEIL_EXPR)
+ output = TREE_OPERAND (output, 0);
+
+ lvalue_or_else (o[i], "invalid lvalue in asm statement");
+ }
/* Perform default conversions on array and function inputs. */
/* Don't do this for other types--
}
else
{
- tree t = convert_for_assignment (valtype, retval, "return",
+ tree t = convert_for_assignment (valtype, retval, _("return"),
NULL_TREE, NULL_TREE, 0);
tree res = DECL_RESULT (current_function_decl);
tree inner;
c_expand_start_case (exp)
tree exp;
{
- register enum tree_code code = TREE_CODE (TREE_TYPE (exp));
- tree type = TREE_TYPE (exp);
+ register enum tree_code code;
+ tree type;
+
+ if (TREE_CODE (exp) == ERROR_MARK)
+ return exp;
+
+ code = TREE_CODE (TREE_TYPE (exp));
+ type = TREE_TYPE (exp);
if (code != INTEGER_TYPE && code != ENUMERAL_TYPE && code != ERROR_MARK)
{
type = TYPE_MAIN_VARIANT (TREE_TYPE (exp));
if (warn_traditional
+ && ! in_system_header
&& (type == long_integer_type_node
|| type == long_unsigned_type_node))
pedwarn ("`long' switch expression not converted to `int' in ANSI C");