diff options
Diffstat (limited to 'gcc/ada/gcc-interface')
-rw-r--r-- | gcc/ada/gcc-interface/cuintp.c | 60 | ||||
-rw-r--r-- | gcc/ada/gcc-interface/decl.c | 18 | ||||
-rw-r--r-- | gcc/ada/gcc-interface/gigi.h | 21 | ||||
-rw-r--r-- | gcc/ada/gcc-interface/trans.c | 52 | ||||
-rw-r--r-- | gcc/ada/gcc-interface/utils.c | 8 |
5 files changed, 91 insertions, 68 deletions
diff --git a/gcc/ada/gcc-interface/cuintp.c b/gcc/ada/gcc-interface/cuintp.c index 642a71b..31ed801 100644 --- a/gcc/ada/gcc-interface/cuintp.c +++ b/gcc/ada/gcc-interface/cuintp.c @@ -6,7 +6,7 @@ * * * C Implementation File * * * - * Copyright (C) 1992-2009, Free Software Foundation, Inc. * + * Copyright (C) 1992-2010, Free Software Foundation, Inc. * * * * GNAT is free software; you can redistribute it and/or modify it under * * terms of the GNU General Public License as published by the Free Soft- * @@ -142,3 +142,61 @@ UI_To_gnu (Uint Input, tree type) return gnu_ret; } + +/* Similar to UI_From_Int, but take a GCC INTEGER_CST. We use UI_From_Int + when possible, i.e. for a 32-bit signed value, to take advantage of its + built-in caching mechanism. For values of larger magnitude, we compute + digits into a vector and call Vector_To_Uint. */ + +Uint +UI_From_gnu (tree Input) +{ + tree gnu_type = TREE_TYPE (Input), gnu_base, gnu_temp; + /* UI_Base is defined so that 5 Uint digits is sufficient to hold the + largest possible signed 64-bit value. */ + const int Max_For_Dint = 5; + int v[Max_For_Dint], i; + Vector_Template temp; + Int_Vector vec; + +#if HOST_BITS_PER_WIDE_INT == 64 + /* On 64-bit hosts, host_integerp tells whether the input fits in a + signed 64-bit integer. Then a truncation tells whether it fits + in a signed 32-bit integer. */ + if (host_integerp (Input, 0)) + { + HOST_WIDE_INT hw_input = TREE_INT_CST_LOW (Input); + if (hw_input == (int) hw_input) + return UI_From_Int (hw_input); + } + else + return No_Uint; +#else + /* On 32-bit hosts, host_integerp tells whether the input fits in a + signed 32-bit integer. Then a sign test tells whether it fits + in a signed 64-bit integer. */ + if (host_integerp (Input, 0)) + return UI_From_Int (TREE_INT_CST_LOW (Input)); + else if (TREE_INT_CST_HIGH (Input) < 0 + && TYPE_UNSIGNED (gnu_type) + && !(TREE_CODE (gnu_type) == INTEGER_TYPE + && TYPE_IS_SIZETYPE (gnu_type))) + return No_Uint; +#endif + + gnu_base = build_int_cst (gnu_type, UI_Base); + gnu_temp = Input; + + for (i = Max_For_Dint - 1; i >= 0; i--) + { + v[i] = tree_low_cst (fold_build1 (ABS_EXPR, gnu_type, + fold_build2 (TRUNC_MOD_EXPR, gnu_type, + gnu_temp, gnu_base)), + 0); + gnu_temp = fold_build2 (TRUNC_DIV_EXPR, gnu_type, gnu_temp, gnu_base); + } + + temp.Low_Bound = 1, temp.High_Bound = Max_For_Dint; + vec.Array = v, vec.Bounds = &temp; + return Vector_To_Uint (vec, tree_int_cst_sgn (Input) < 0); +} diff --git a/gcc/ada/gcc-interface/decl.c b/gcc/ada/gcc-interface/decl.c index 44c3929..1a42ff7 100644 --- a/gcc/ada/gcc-interface/decl.c +++ b/gcc/ada/gcc-interface/decl.c @@ -6281,7 +6281,9 @@ maybe_pad_type (tree type, tree size, unsigned int align, && !operand_equal_p (size, orig_size, 0) && !(TREE_CODE (size) == INTEGER_CST && TREE_CODE (orig_size) == INTEGER_CST - && tree_int_cst_lt (size, orig_size))) + && (TREE_OVERFLOW (size) + || TREE_OVERFLOW (orig_size) + || tree_int_cst_lt (size, orig_size)))) { Node_Id gnat_error_node = Empty; @@ -7087,7 +7089,7 @@ annotate_value (tree gnu_size) TCode tcode; Node_Ref_Or_Val ops[3], ret; struct tree_int_map **h = NULL; - int size, i; + int i; /* See if we've already saved the value for this node. */ if (EXPR_P (gnu_size)) @@ -7143,17 +7145,7 @@ annotate_value (tree gnu_size) return annotate_value (temp); } - if (!host_integerp (gnu_size, 1)) - return No_Uint; - - size = tree_low_cst (gnu_size, 1); - - /* This peculiar test is to make sure that the size fits in an int - on machines where HOST_WIDE_INT is not "int". */ - if (tree_low_cst (gnu_size, 1) == size) - return UI_From_Int (size); - else - return No_Uint; + return UI_From_gnu (gnu_size); case COMPONENT_REF: /* The only case we handle here is a simple discriminant reference. */ diff --git a/gcc/ada/gcc-interface/gigi.h b/gcc/ada/gcc-interface/gigi.h index f0c5777..d6101be 100644 --- a/gcc/ada/gcc-interface/gigi.h +++ b/gcc/ada/gcc-interface/gigi.h @@ -232,28 +232,25 @@ extern bool Sloc_to_locus (Source_Ptr Sloc, location_t *locus); /* Post an error message. MSG is the error message, properly annotated. NODE is the node at which to post the error and the node to use for the - "&" substitution. */ + '&' substitution. */ extern void post_error (const char *msg, Node_Id node); -/* Similar, but NODE is the node at which to post the error and ENT - is the node to use for the "&" substitution. */ +/* Similar to post_error, but NODE is the node at which to post the error and + ENT is the node to use for the '&' substitution. */ extern void post_error_ne (const char *msg, Node_Id node, Entity_Id ent); -/* Similar, but NODE is the node at which to post the error, ENT is the node - to use for the "&" substitution, and NUM is the number to use for ^. */ +/* Similar to post_error_ne, but NUM is the number to use for the '^'. */ extern void post_error_ne_num (const char *msg, Node_Id node, Entity_Id ent, int num); -/* Similar to post_error_ne_num, but T is a GCC tree representing the number - to write. If the tree represents a constant that fits within a - host integer, the text inside curly brackets in MSG will be output - (presumably including a '^'). Otherwise that text will not be output - and the text inside square brackets will be output instead. */ +/* Similar to post_error_ne, but T is a GCC tree representing the number to + write. If T represents a constant, the text inside curly brackets in + MSG will be output (presumably including a '^'). Otherwise it will not + be output and the text inside square brackets will be output instead. */ extern void post_error_ne_tree (const char *msg, Node_Id node, Entity_Id ent, tree t); -/* Similar to post_error_ne_tree, except that NUM is a second integer to write - in the message. */ +/* Similar to post_error_ne_tree, but NUM is a second integer to write. */ extern void post_error_ne_tree_2 (const char *msg, Node_Id node, Entity_Id ent, tree t, int num); diff --git a/gcc/ada/gcc-interface/trans.c b/gcc/ada/gcc-interface/trans.c index ee8eedc..7cf15da 100644 --- a/gcc/ada/gcc-interface/trans.c +++ b/gcc/ada/gcc-interface/trans.c @@ -7404,7 +7404,7 @@ decode_name (const char *name) /* Post an error message. MSG is the error message, properly annotated. NODE is the node at which to post the error and the node to use for the - "&" substitution. */ + '&' substitution. */ void post_error (const char *msg, Node_Id node) @@ -7418,8 +7418,8 @@ post_error (const char *msg, Node_Id node) Error_Msg_N (fp, node); } -/* Similar, but NODE is the node at which to post the error and ENT - is the node to use for the "&" substitution. */ +/* Similar to post_error, but NODE is the node at which to post the error and + ENT is the node to use for the '&' substitution. */ void post_error_ne (const char *msg, Node_Id node, Entity_Id ent) @@ -7433,56 +7433,37 @@ post_error_ne (const char *msg, Node_Id node, Entity_Id ent) Error_Msg_NE (fp, node, ent); } -/* Similar, but NODE is the node at which to post the error, ENT is the node - to use for the "&" substitution, and NUM is the number to use for ^. */ +/* Similar to post_error_ne, but NUM is the number to use for the '^'. */ void post_error_ne_num (const char *msg, Node_Id node, Entity_Id ent, int num) { - String_Template temp; - Fat_Pointer fp; - - temp.Low_Bound = 1, temp.High_Bound = strlen (msg); - fp.Array = msg, fp.Bounds = &temp; Error_Msg_Uint_1 = UI_From_Int (num); - - if (Present (node)) - Error_Msg_NE (fp, node, ent); + post_error_ne (msg, node, ent); } -/* Similar to post_error_ne_num, but T is a GCC tree representing the - number to write. If the tree represents a constant that fits within - a host integer, the text inside curly brackets in MSG will be output - (presumably including a '^'). Otherwise that text will not be output - and the text inside square brackets will be output instead. */ +/* Similar to post_error_ne, but T is a GCC tree representing the number to + write. If T represents a constant, the text inside curly brackets in + MSG will be output (presumably including a '^'). Otherwise it will not + be output and the text inside square brackets will be output instead. */ void post_error_ne_tree (const char *msg, Node_Id node, Entity_Id ent, tree t) { - char *newmsg = XALLOCAVEC (char, strlen (msg) + 1); - String_Template temp = {1, 0}; - Fat_Pointer fp; + char *new_msg = XALLOCAVEC (char, strlen (msg) + 1); char start_yes, end_yes, start_no, end_no; const char *p; char *q; - fp.Array = newmsg, fp.Bounds = &temp; - - if (host_integerp (t, 1) -#if HOST_BITS_PER_WIDE_INT > HOST_BITS_PER_INT - && - compare_tree_int - (t, (((unsigned HOST_WIDE_INT) 1 << (HOST_BITS_PER_INT - 1)) - 1)) < 0 -#endif - ) + if (TREE_CODE (t) == INTEGER_CST) { - Error_Msg_Uint_1 = UI_From_Int (tree_low_cst (t, 1)); + Error_Msg_Uint_1 = UI_From_gnu (t); start_yes = '{', end_yes = '}', start_no = '[', end_no = ']'; } else start_yes = '[', end_yes = ']', start_no = '{', end_no = '}'; - for (p = msg, q = newmsg; *p; p++) + for (p = msg, q = new_msg; *p; p++) { if (*p == start_yes) for (p++; *p != end_yes; p++) @@ -7496,13 +7477,10 @@ post_error_ne_tree (const char *msg, Node_Id node, Entity_Id ent, tree t) *q = 0; - temp.High_Bound = strlen (newmsg); - if (Present (node)) - Error_Msg_NE (fp, node, ent); + post_error_ne (new_msg, node, ent); } -/* Similar to post_error_ne_tree, except that NUM is a second integer to write - in the message. */ +/* Similar to post_error_ne_tree, but NUM is a second integer to write. */ void post_error_ne_tree_2 (const char *msg, Node_Id node, Entity_Id ent, tree t, diff --git a/gcc/ada/gcc-interface/utils.c b/gcc/ada/gcc-interface/utils.c index 27959ea..68a0d0f 100644 --- a/gcc/ada/gcc-interface/utils.c +++ b/gcc/ada/gcc-interface/utils.c @@ -2228,8 +2228,7 @@ max_size (tree exp, bool max_p) In that case, if one side overflows, return the other. sizetype is signed, but we know sizes are non-negative. Likewise, handle a MINUS_EXPR or PLUS_EXPR with the LHS - overflowing or the maximum possible value and the RHS - a variable. */ + overflowing and the RHS a variable. */ if (max_p && code == MIN_EXPR && TREE_CODE (rhs) == INTEGER_CST @@ -2241,9 +2240,8 @@ max_size (tree exp, bool max_p) && TREE_OVERFLOW (lhs)) return rhs; else if ((code == MINUS_EXPR || code == PLUS_EXPR) - && ((TREE_CODE (lhs) == INTEGER_CST - && TREE_OVERFLOW (lhs)) - || operand_equal_p (lhs, TYPE_MAX_VALUE (type), 0)) + && TREE_CODE (lhs) == INTEGER_CST + && TREE_OVERFLOW (lhs) && !TREE_CONSTANT (rhs)) return lhs; else |