aboutsummaryrefslogtreecommitdiff
path: root/gcc/builtins.c
diff options
context:
space:
mode:
authorRichard Kenner <kenner@vlsi1.ultra.nyu.edu>2000-02-27 21:39:40 +0000
committerRichard Kenner <kenner@gcc.gnu.org>2000-02-27 16:39:40 -0500
commitfed3cef0dbbd17e3d7b8860f42cd8490f0325340 (patch)
treeda73c398c9c03435ecc0d3821031b7c0fe89911d /gcc/builtins.c
parent43931371e2321b6c50c3e0b9095d46606ec48ce1 (diff)
downloadgcc-fed3cef0dbbd17e3d7b8860f42cd8490f0325340.zip
gcc-fed3cef0dbbd17e3d7b8860f42cd8490f0325340.tar.gz
gcc-fed3cef0dbbd17e3d7b8860f42cd8490f0325340.tar.bz2
builtins.c (c_strlen): Use size_diffop and return ssizetype value.
* builtins.c (c_strlen): Use size_diffop and return ssizetype value. (expand_builtin_strcpy): Pass correct type to size_binop. (expand_builtin_strcmp): Likewise. Clean up conditional structure. * c-decl.c (init_decl_processing): Don't call set_sizetype twice. (complete_array_type): Don't use size_binop for MAXINDEX. * c-typeck.c (c_sizeof): Use size_one_node and TYPE_SIZE_UNIT. (c_sizeof_nowarn, c_size_in_bytes): Likewise. (c_alignof): Use size_one_node. (build_unary_op): Pass arg of proper type to size_binop. (really_start_incremental_init, push_init_level): Use sizetype for constructor{,_bit,_unfilled}_index. (pop_init_label, output_init_element): Likewise. (output_pending_init_elements, process_init_element): Likewise. * calls.c (compute_argument_block_size): Field VAR is ssizetype. * expr.c (store_expr): Use size_int. (store_constructor): Use proper types for size_binop args. (get_inner_reference, expand_expr, case ARRAY_REF): Likewise. (expand_expr_unaligned): Likewise. (string_contant): Return object of sizetype. * expr.h (SUB_PARM_SIZE): Call size_diffop and pass proper types. (ARGS_SIZE_RTX): Call ARGS_SIZE_TREE. (ARGS_SIZE_TREE): Pass proper types to size_binop. * fold-const.c (int_const_binop): Refine when size_int is called. (fold_convert): Likewise. (size_int_wide): Rework to take KIND as arg, only take low order bits, handle new sizetype_tab datatype, and chain entries in size_table. (size_int_type_wide): New function. (size_binop): Validate types of arguments. (ssize_binop): Deleted. (size_diffop): New function. (extract_muldiv): Only fold division into multiplication for sizetypes. * function.c (assign_parms): Use size_diffop and make sure VAR field is of ssizetype; also pass proper type to size_binop. (locate_and_pad_parm, pad_to_arg_alignment): Likewise. (round_down): Deleted from here. * store-layout.c (sizetype_tab): Now an array. (sizetype_set, early_root_list): New variables. (variable_size): Use size_one_node. (round_up): Pass proper type to size_binop. (round_down): Moved to here and corrected as above. (layout_record): Pass proper arg types to size_binop. (layout_type): Likewise. If sizetype_set is zero, record the type just laid out. (make_unsigned_type): Don't call set_sizetype; (make_signed_type): Likewise; also, call fixup_signed_type. (initialize_sizetypes): New function. (set_sizetype): Make copy of types, set TYPE_IS_SIZETYPE, and set name of bitsizetype to "bit_size_type". Fix up type of sizes of all types made before call. * tm.texi (ROUND_TYPE_SIZE_UNIT): New macro. * tree.c (fix_sizetype): Deleted. (build_common_tree_nodes): Call initialize_sizetypes. (build_common_tree_nodes_2): Don't call fix_sizetype. * tree.h (TYPE_IS_SIZETYPE): New macro. (initialize_sizetype): New declaration. (enum size_type_kind): New type. (struct sizetype_tab): Deleted. (sizetype_tab): Now array; adjust sizetype macros. (size_diffop, size_int_type_wide): New functions. (size_int_wide): Change number of args and type; access macros changed. (ssize_int, sbitsize_int): New macros. * config/i960/i960.h (ROUND_TYPE_SIZE): Use size_int. (ROUND_TYPE_SIZE_UNIT): New macro. * ch/actions.c (chill_convert_for_assignment): Don't use size_binop for things that aren't sizes. (expand_varying_length_assignment): Likewise. * ch/convert.c (digest_array_tuple, convert): Likewise. * ch/typeck.c (build_chill_slice, smash_dummy_type): Likewise. (build_chill_slice_with_range): Likewise. (build_chill_slice_with_length): Likewise. (build_array_from_set): Adjust types for size_binop. * ch/expr.c (build_concat_expr, build_chill_repetition_op): Likewise. (build_chill_sizeof): Use TYPE_SIZE_UNIT. * ch/tree.c (build_string_type): Pass proper type to size_binop. * cp/class.c (dfs_build_vtable_offset_vtbl_entries): Don't use size_binop on things that are not sizes; ssize_binop deleted. Call size_diffop when appropriate. (dfs_build_vcall_offset_vtbl_entries): Likewise. (build_primary_vtable, build_secondary_vtable): Likewise. (dfs_set_offset_for_unshared_vbases, dfs_modify_vtables): Likewise. Variable I is HOST_WIDE_INT. (get_vfield_offset): Pass proper types to size_binop. (size_extra_vtbl_entries, layout_virtual_bases): Likewise. (finish_struct_1): Likewise. (skip_rtti_stuff): Arg N is now pointer to signed. (layout_class_type): Use size_zero_node. * cp/cp-tree.h (skip_rtti_stuff): Arg N is pointer to signed. * cp/cvt.c (cp_convert_to_pointer): Pass proper types to size_binop. * cp/decl.c (complete_arry_type): Pass proper types to size_binop. (xref_basetypes): BINFO_OFFSET is sizetype. * cp/error.c (dump_expr): Don't use size_binop non-sizes. * cp/expr.c (cplus_expand_constant): Pass proper types to size_binop. * cp/init.c (construct_virtual_bases): Fix type error. (build_vec_delete_1): Pass proper type to size_binop and don't fold result. * cp/lex.c (cp_make_lang_type): BINFO_OFFSET is sizetype. * cp/rtti.c (get_base_offset): Pass proper type to size_binop. * cp/search.c (dfs_find_vbases): Fix type error. (expand_upcast_fixups): Arg to skip_rtti_stuff is pointer to signed. (dfs_get_vbase_types): BINFO_OFFSET is sizetype. * cp/tree.c (debug_binfo): Variable N is signed. Use HOST_WIDE_INT_PRINT_DEC. * cp/typeck.c (comptypes): sizetype is same as equivalent integer type. (c_sizeof, c_sizeof_nowarn, expr_sizeof): Use TYPE_SIZE_UNIT, size_one_node and size_zero_node. (c_alignof): Use size_one_node. (build_component_addr): Pass proper types to size_binop. (expand_ptrmemfunc_cst): Don't use size_binop on non-sizes. * f/com.c (ffecom_arrayref_): Convert args to size_binop to proper type. (ffecom_tree_canonize_ptr_): Don't use size_binop for non-sizes. (ffecom_tree_canonize_ref_): Likewise. (type_for_mode): Handle TImode. * f/ste.c (ffeste_io_dofio_, ffeste_io_douio_): Use TYPE_SIZE_UNIT. (ffeste_io_ciclist_): Likewise. * java/expr.c (build_java_ret): Pass proper type to size_binop. From-SVN: r32225
Diffstat (limited to 'gcc/builtins.c')
-rw-r--r--gcc/builtins.c58
1 files changed, 38 insertions, 20 deletions
diff --git a/gcc/builtins.c b/gcc/builtins.c
index 3473740..e32d0bd 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -164,6 +164,8 @@ get_pointer_alignment (exp, max_align)
way, because it could contain a zero byte in the middle.
TREE_STRING_LENGTH is the size of the character array, not the string.
+ The value returned is of type `ssizetype'.
+
Unfortunately, string_constant can't access the values of const char
arrays with initializers, so neither can we do so here. */
@@ -178,25 +180,29 @@ c_strlen (src)
src = string_constant (src, &offset_node);
if (src == 0)
return 0;
+
max = TREE_STRING_LENGTH (src);
ptr = TREE_STRING_POINTER (src);
+
if (offset_node && TREE_CODE (offset_node) != INTEGER_CST)
{
/* If the string has an internal zero byte (e.g., "foo\0bar"), we can't
compute the offset to the following null if we don't know where to
start searching for it. */
int i;
+
for (i = 0; i < max; i++)
if (ptr[i] == 0)
return 0;
+
/* We don't know the starting offset, but we do know that the string
has no internal zero bytes. We can assume that the offset falls
within the bounds of the string; otherwise, the programmer deserves
what he gets. Subtract the offset from the length of the string,
- and return that. */
- /* This would perhaps not be valid if we were dealing with named
- arrays in addition to literal string constants. */
- return size_binop (MINUS_EXPR, size_int (max), offset_node);
+ and return that. This would perhaps not be valid if we were dealing
+ with named arrays in addition to literal string constants. */
+
+ return size_diffop (size_int (max), offset_node);
}
/* We have a known offset into the string. Start searching there for
@@ -210,6 +216,7 @@ c_strlen (src)
return 0;
offset = TREE_INT_CST_LOW (offset_node);
}
+
/* If the offset is known to be out of bounds, warn, and call strlen at
runtime. */
if (offset < 0 || offset > max)
@@ -217,18 +224,20 @@ c_strlen (src)
warning ("offset outside bounds of constant string");
return 0;
}
+
/* Use strlen to search for the first zero byte. Since any strings
constructed with build_string will have nulls appended, we win even
if we get handed something like (char[4])"abcd".
Since OFFSET is our starting index into the string, no further
calculation is needed. */
- return size_int (strlen (ptr + offset));
+ return ssize_int (strlen (ptr + offset));
}
/* Given TEM, a pointer to a stack frame, follow the dynamic chain COUNT
times to get the address of either a higher stack frame, or a return
address located within it (depending on FNDECL_CODE). */
+
rtx
expand_builtin_return_addr (fndecl_code, count, tem)
enum built_in_function fndecl_code;
@@ -1437,6 +1446,7 @@ expand_builtin_memcpy (arglist)
/* Expand expression EXP, which is a call to the strcpy builtin. Return 0
if we failed the caller should emit a normal call. */
+
static rtx
expand_builtin_strcpy (exp)
tree exp;
@@ -1448,7 +1458,8 @@ expand_builtin_strcpy (exp)
/* Arg could be non-pointer if user redeclared this fcn wrong. */
|| TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
|| TREE_CHAIN (arglist) == 0
- || TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (arglist)))) != POINTER_TYPE)
+ || (TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (arglist))))
+ != POINTER_TYPE))
return 0;
else
{
@@ -1457,11 +1468,12 @@ expand_builtin_strcpy (exp)
if (len == 0)
return 0;
- len = size_binop (PLUS_EXPR, len, integer_one_node);
-
+ len = size_binop (PLUS_EXPR, len, ssize_int (1));
chainon (arglist, build_tree_list (NULL_TREE, len));
}
+
result = expand_builtin_memcpy (arglist);
+
if (! result)
TREE_CHAIN (TREE_CHAIN (arglist)) = 0;
return result;
@@ -1469,6 +1481,7 @@ expand_builtin_strcpy (exp)
/* Expand expression EXP, which is a call to the memset builtin. Return 0
if we failed the caller should emit a normal call. */
+
static rtx
expand_builtin_memset (exp)
tree exp;
@@ -1610,6 +1623,7 @@ expand_builtin_memcmp (exp, arglist, target)
/* Expand expression EXP, which is a call to the strcmp builtin. Return 0
if we failed the caller should emit a normal call, otherwise try to get
the result in TARGET, if convenient. */
+
static rtx
expand_builtin_strcmp (exp, target)
tree exp;
@@ -1625,21 +1639,24 @@ expand_builtin_strcmp (exp, target)
/* Arg could be non-pointer if user redeclared this fcn wrong. */
|| TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
|| TREE_CHAIN (arglist) == 0
- || TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (arglist)))) != POINTER_TYPE)
+ || (TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (arglist))))
+ != POINTER_TYPE))
return 0;
- else if (!HAVE_cmpstrsi)
+
+ else if (! HAVE_cmpstrsi)
return 0;
{
tree arg1 = TREE_VALUE (arglist);
tree arg2 = TREE_VALUE (TREE_CHAIN (arglist));
- tree len, len2;
+ tree len = c_strlen (arg1);
+ tree len2 = c_strlen (arg2);
rtx result;
- len = c_strlen (arg1);
+
if (len)
- len = size_binop (PLUS_EXPR, integer_one_node, len);
- len2 = c_strlen (arg2);
+ len = size_binop (PLUS_EXPR, ssize_int (1), len);
+
if (len2)
- len2 = size_binop (PLUS_EXPR, integer_one_node, len2);
+ len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
/* If we don't have a constant length for the first, use the length
of the second, if we know it. We don't require a constant for
@@ -1651,6 +1668,7 @@ expand_builtin_strcmp (exp, target)
two fixed strings, or if the code was machine-generated. We should
add some code to the `memcmp' handler below to deal with such
situations, someday. */
+
if (!len || TREE_CODE (len) != INTEGER_CST)
{
if (len2)
@@ -1658,16 +1676,15 @@ expand_builtin_strcmp (exp, target)
else if (len == 0)
return 0;
}
- else if (len2 && TREE_CODE (len2) == INTEGER_CST)
- {
- if (tree_int_cst_lt (len2, len))
- len = len2;
- }
+ else if (len2 && TREE_CODE (len2) == INTEGER_CST
+ && tree_int_cst_lt (len2, len))
+ len = len2;
chainon (arglist, build_tree_list (NULL_TREE, len));
result = expand_builtin_memcmp (exp, arglist, target);
if (! result)
TREE_CHAIN (TREE_CHAIN (arglist)) = 0;
+
return result;
}
}
@@ -1675,6 +1692,7 @@ expand_builtin_strcmp (exp, target)
/* Expand a call to __builtin_saveregs, generating the result in TARGET,
if that's convenient. */
+
rtx
expand_builtin_saveregs ()
{