Commit a531043b by Eric Botcazou Committed by Eric Botcazou

decl.c (elaborate_expression_1): Remove GNAT_EXPR parameter and move check for…

decl.c (elaborate_expression_1): Remove GNAT_EXPR parameter and move check for static expression to...

	* gcc-interface/decl.c (elaborate_expression_1): Remove GNAT_EXPR
	parameter and move check for static expression to...
	(elaborate_expression): ...here.  Adjust call to above function.
	(gnat_to_gnu_entity): Likewise for all calls.  Use correct arguments
	in calls to elaborate_expression.
	(elaborate_entity): Likewise.
	(substitution_list): Likewise.
	(maybe_variable): Fix formatting.
	(substitute_in_type) <REAL_TYPE>: Merge with INTEGER_TYPE case and add
	missing guard.
	* gcc-interface/trans.c (protect_multiple_eval): Minor cleanup.

From-SVN: r147530
parent fe049033
2009-05-14 Eric Botcazou <ebotcazou@adacore.com>
* gcc-interface/decl.c (elaborate_expression_1): Remove GNAT_EXPR
parameter and move check for static expression to...
(elaborate_expression): ...here. Adjust call to above function.
(gnat_to_gnu_entity): Likewise for all calls. Use correct arguments
in calls to elaborate_expression.
(elaborate_entity): Likewise.
(substitution_list): Likewise.
(maybe_variable): Fix formatting.
(substitute_in_type) <REAL_TYPE>: Merge with INTEGER_TYPE case and add
missing guard.
* gcc-interface/trans.c (protect_multiple_eval): Minor cleanup.
2009-05-07 Arnaud Charlet <charlet@adacore.com> 2009-05-07 Arnaud Charlet <charlet@adacore.com>
* gcc-interface/Make-lang.in: Update dependencies. * gcc-interface/Make-lang.in: Update dependencies.
......
...@@ -128,8 +128,7 @@ static void prepend_one_attribute_to (struct attrib **, ...@@ -128,8 +128,7 @@ static void prepend_one_attribute_to (struct attrib **,
static void prepend_attributes (Entity_Id, struct attrib **); static void prepend_attributes (Entity_Id, struct attrib **);
static tree elaborate_expression (Node_Id, Entity_Id, tree, bool, bool, bool); static tree elaborate_expression (Node_Id, Entity_Id, tree, bool, bool, bool);
static bool is_variable_size (tree); static bool is_variable_size (tree);
static tree elaborate_expression_1 (Node_Id, Entity_Id, tree, tree, static tree elaborate_expression_1 (tree, Entity_Id, tree, bool, bool);
bool, bool);
static tree make_packable_type (tree, bool); static tree make_packable_type (tree, bool);
static tree gnat_to_gnu_field (Entity_Id, tree, int, bool); static tree gnat_to_gnu_field (Entity_Id, tree, int, bool);
static tree gnat_to_gnu_param (Entity_Id, Mechanism_Type, Entity_Id, bool, static tree gnat_to_gnu_param (Entity_Id, Mechanism_Type, Entity_Id, bool,
...@@ -1563,15 +1562,15 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition) ...@@ -1563,15 +1562,15 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
TYPE_MIN_VALUE (gnu_type) TYPE_MIN_VALUE (gnu_type)
= convert (TREE_TYPE (gnu_type), = convert (TREE_TYPE (gnu_type),
elaborate_expression (Type_Low_Bound (gnat_entity), elaborate_expression (Type_Low_Bound (gnat_entity),
gnat_entity, gnat_entity, get_identifier ("L"),
get_identifier ("L"), definition, 1, definition, true,
Needs_Debug_Info (gnat_entity))); Needs_Debug_Info (gnat_entity)));
TYPE_MAX_VALUE (gnu_type) TYPE_MAX_VALUE (gnu_type)
= convert (TREE_TYPE (gnu_type), = convert (TREE_TYPE (gnu_type),
elaborate_expression (Type_High_Bound (gnat_entity), elaborate_expression (Type_High_Bound (gnat_entity),
gnat_entity, gnat_entity, get_identifier ("U"),
get_identifier ("U"), definition, 1, definition, true,
Needs_Debug_Info (gnat_entity))); Needs_Debug_Info (gnat_entity)));
/* One of the above calls might have caused us to be elaborated, /* One of the above calls might have caused us to be elaborated,
...@@ -1747,14 +1746,14 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition) ...@@ -1747,14 +1746,14 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
= convert (TREE_TYPE (gnu_type), = convert (TREE_TYPE (gnu_type),
elaborate_expression (Type_Low_Bound (gnat_entity), elaborate_expression (Type_Low_Bound (gnat_entity),
gnat_entity, get_identifier ("L"), gnat_entity, get_identifier ("L"),
definition, 1, definition, true,
Needs_Debug_Info (gnat_entity))); Needs_Debug_Info (gnat_entity)));
TYPE_MAX_VALUE (gnu_type) TYPE_MAX_VALUE (gnu_type)
= convert (TREE_TYPE (gnu_type), = convert (TREE_TYPE (gnu_type),
elaborate_expression (Type_High_Bound (gnat_entity), elaborate_expression (Type_High_Bound (gnat_entity),
gnat_entity, get_identifier ("U"), gnat_entity, get_identifier ("U"),
definition, 1, definition, true,
Needs_Debug_Info (gnat_entity))); Needs_Debug_Info (gnat_entity)));
/* One of the above calls might have caused us to be elaborated, /* One of the above calls might have caused us to be elaborated,
...@@ -2434,9 +2433,9 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition) ...@@ -2434,9 +2433,9 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
tree eltype = TREE_TYPE (gnu_arr_type); tree eltype = TREE_TYPE (gnu_arr_type);
TYPE_SIZE (gnu_arr_type) TYPE_SIZE (gnu_arr_type)
= elaborate_expression_1 (gnat_entity, gnat_entity, = elaborate_expression_1 (TYPE_SIZE (gnu_arr_type),
TYPE_SIZE (gnu_arr_type), gnat_entity, gnu_str_name,
gnu_str_name, definition, 0); definition, false);
/* ??? For now, store the size as a multiple of the /* ??? For now, store the size as a multiple of the
alignment of the element type in bytes so that we alignment of the element type in bytes so that we
...@@ -2445,12 +2444,12 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition) ...@@ -2445,12 +2444,12 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
= build_binary_op = build_binary_op
(MULT_EXPR, sizetype, (MULT_EXPR, sizetype,
elaborate_expression_1 elaborate_expression_1
(gnat_entity, gnat_entity, (build_binary_op (EXACT_DIV_EXPR, sizetype,
build_binary_op (EXACT_DIV_EXPR, sizetype,
TYPE_SIZE_UNIT (gnu_arr_type), TYPE_SIZE_UNIT (gnu_arr_type),
size_int (TYPE_ALIGN (eltype) size_int (TYPE_ALIGN (eltype)
/ BITS_PER_UNIT)), / BITS_PER_UNIT)),
concat_name (gnu_str_name, "A_U"), definition, 0), gnat_entity, concat_name (gnu_str_name, "A_U"),
definition, false),
size_int (TYPE_ALIGN (eltype) / BITS_PER_UNIT)); size_int (TYPE_ALIGN (eltype) / BITS_PER_UNIT));
/* ??? create_type_decl is not invoked on the inner types so /* ??? create_type_decl is not invoked on the inner types so
...@@ -4515,19 +4514,17 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition) ...@@ -4515,19 +4514,17 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
TYPE_SIZE (gnu_type), 0)) TYPE_SIZE (gnu_type), 0))
{ {
TYPE_SIZE (gnu_type) TYPE_SIZE (gnu_type)
= elaborate_expression_1 (gnat_entity, gnat_entity, = elaborate_expression_1 (TYPE_SIZE (gnu_type),
TYPE_SIZE (gnu_type), gnat_entity, get_identifier ("SIZE"),
get_identifier ("SIZE"), definition, false);
definition, 0);
SET_TYPE_ADA_SIZE (gnu_type, TYPE_SIZE (gnu_type)); SET_TYPE_ADA_SIZE (gnu_type, TYPE_SIZE (gnu_type));
} }
else else
{ {
TYPE_SIZE (gnu_type) TYPE_SIZE (gnu_type)
= elaborate_expression_1 (gnat_entity, gnat_entity, = elaborate_expression_1 (TYPE_SIZE (gnu_type),
TYPE_SIZE (gnu_type), gnat_entity, get_identifier ("SIZE"),
get_identifier ("SIZE"), definition, false);
definition, 0);
/* ??? For now, store the size as a multiple of the alignment /* ??? For now, store the size as a multiple of the alignment
in bytes so that we can see the alignment from the tree. */ in bytes so that we can see the alignment from the tree. */
...@@ -4535,23 +4532,21 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition) ...@@ -4535,23 +4532,21 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
= build_binary_op = build_binary_op
(MULT_EXPR, sizetype, (MULT_EXPR, sizetype,
elaborate_expression_1 elaborate_expression_1
(gnat_entity, gnat_entity, (build_binary_op (EXACT_DIV_EXPR, sizetype,
build_binary_op (EXACT_DIV_EXPR, sizetype,
TYPE_SIZE_UNIT (gnu_type), TYPE_SIZE_UNIT (gnu_type),
size_int (TYPE_ALIGN (gnu_type) size_int (TYPE_ALIGN (gnu_type)
/ BITS_PER_UNIT)), / BITS_PER_UNIT)),
get_identifier ("SIZE_A_UNIT"), gnat_entity, get_identifier ("SIZE_A_UNIT"),
definition, 0), definition, false),
size_int (TYPE_ALIGN (gnu_type) / BITS_PER_UNIT)); size_int (TYPE_ALIGN (gnu_type) / BITS_PER_UNIT));
if (TREE_CODE (gnu_type) == RECORD_TYPE) if (TREE_CODE (gnu_type) == RECORD_TYPE)
SET_TYPE_ADA_SIZE SET_TYPE_ADA_SIZE
(gnu_type, (gnu_type,
elaborate_expression_1 (gnat_entity, elaborate_expression_1 (TYPE_ADA_SIZE (gnu_type),
gnat_entity, gnat_entity,
TYPE_ADA_SIZE (gnu_type),
get_identifier ("RM_SIZE"), get_identifier ("RM_SIZE"),
definition, 0)); definition, false));
} }
} }
...@@ -4577,13 +4572,12 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition) ...@@ -4577,13 +4572,12 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
= build_binary_op = build_binary_op
(MULT_EXPR, sizetype, (MULT_EXPR, sizetype,
elaborate_expression_1 elaborate_expression_1
(gnat_temp, gnat_temp, (build_binary_op (EXACT_DIV_EXPR, sizetype,
build_binary_op (EXACT_DIV_EXPR, sizetype,
DECL_FIELD_OFFSET (gnu_field), DECL_FIELD_OFFSET (gnu_field),
size_int (DECL_OFFSET_ALIGN (gnu_field) size_int (DECL_OFFSET_ALIGN (gnu_field)
/ BITS_PER_UNIT)), / BITS_PER_UNIT)),
get_identifier ("OFFSET"), gnat_temp, get_identifier ("OFFSET"),
definition, 0), definition, false),
size_int (DECL_OFFSET_ALIGN (gnu_field) / BITS_PER_UNIT)); size_int (DECL_OFFSET_ALIGN (gnu_field) / BITS_PER_UNIT));
/* ??? The context of gnu_field is not necessarily gnu_type so /* ??? The context of gnu_field is not necessarily gnu_type so
...@@ -5265,10 +5259,10 @@ elaborate_entity (Entity_Id gnat_entity) ...@@ -5265,10 +5259,10 @@ elaborate_entity (Entity_Id gnat_entity)
conversions on bounds of real types. */ conversions on bounds of real types. */
if (!Raises_Constraint_Error (gnat_lb)) if (!Raises_Constraint_Error (gnat_lb))
elaborate_expression (gnat_lb, gnat_entity, get_identifier ("L"), elaborate_expression (gnat_lb, gnat_entity, get_identifier ("L"),
1, 0, Needs_Debug_Info (gnat_entity)); true, false, Needs_Debug_Info (gnat_entity));
if (!Raises_Constraint_Error (gnat_hb)) if (!Raises_Constraint_Error (gnat_hb))
elaborate_expression (gnat_hb, gnat_entity, get_identifier ("U"), elaborate_expression (gnat_hb, gnat_entity, get_identifier ("U"),
1, 0, Needs_Debug_Info (gnat_entity)); true, false, Needs_Debug_Info (gnat_entity));
break; break;
} }
...@@ -5304,8 +5298,8 @@ elaborate_entity (Entity_Id gnat_entity) ...@@ -5304,8 +5298,8 @@ elaborate_entity (Entity_Id gnat_entity)
/* ??? For now, ignore access discriminants. */ /* ??? For now, ignore access discriminants. */
if (!Is_Access_Type (Etype (Node (gnat_discriminant_expr)))) if (!Is_Access_Type (Etype (Node (gnat_discriminant_expr))))
elaborate_expression (Node (gnat_discriminant_expr), elaborate_expression (Node (gnat_discriminant_expr),
gnat_entity, gnat_entity, get_entity_name (gnat_field),
get_entity_name (gnat_field), 1, 0, 0); true, false, false);
} }
break; break;
...@@ -5457,7 +5451,7 @@ substitution_list (Entity_Id gnat_subtype, Entity_Id gnat_type, ...@@ -5457,7 +5451,7 @@ substitution_list (Entity_Id gnat_subtype, Entity_Id gnat_type,
elaborate_expression elaborate_expression
(Node (gnat_value), gnat_subtype, (Node (gnat_value), gnat_subtype,
get_entity_name (gnat_discrim), definition, get_entity_name (gnat_discrim), definition,
1, 0), true, false),
gnu_list); gnu_list);
return gnu_list; return gnu_list;
...@@ -5591,63 +5585,66 @@ prepend_attributes (Entity_Id gnat_entity, struct attrib ** attr_list) ...@@ -5591,63 +5585,66 @@ prepend_attributes (Entity_Id gnat_entity, struct attrib ** attr_list)
} }
} }
/* Called when we need to protect a variable object using a save_expr. */ /* Called when we need to protect a variable object using a SAVE_EXPR. */
tree tree
maybe_variable (tree gnu_operand) maybe_variable (tree gnu_operand)
{ {
if (TREE_CONSTANT (gnu_operand) || TREE_READONLY (gnu_operand) if (TREE_CONSTANT (gnu_operand)
|| TREE_READONLY (gnu_operand)
|| TREE_CODE (gnu_operand) == SAVE_EXPR || TREE_CODE (gnu_operand) == SAVE_EXPR
|| TREE_CODE (gnu_operand) == NULL_EXPR) || TREE_CODE (gnu_operand) == NULL_EXPR)
return gnu_operand; return gnu_operand;
if (TREE_CODE (gnu_operand) == UNCONSTRAINED_ARRAY_REF) if (TREE_CODE (gnu_operand) == UNCONSTRAINED_ARRAY_REF)
{ {
tree gnu_result = build1 (UNCONSTRAINED_ARRAY_REF, tree gnu_result
TREE_TYPE (gnu_operand), = build1 (UNCONSTRAINED_ARRAY_REF, TREE_TYPE (gnu_operand),
variable_size (TREE_OPERAND (gnu_operand, 0))); variable_size (TREE_OPERAND (gnu_operand, 0)));
TREE_READONLY (gnu_result) = TREE_STATIC (gnu_result) TREE_READONLY (gnu_result) = TREE_STATIC (gnu_result)
= TYPE_READONLY (TREE_TYPE (TREE_TYPE (gnu_operand))); = TYPE_READONLY (TREE_TYPE (TREE_TYPE (gnu_operand)));
return gnu_result; return gnu_result;
} }
else
return variable_size (gnu_operand); return variable_size (gnu_operand);
} }
/* Given a GNAT tree GNAT_EXPR, for an expression which is a value within a /* Given a GNAT tree GNAT_EXPR, for an expression which is a value within a
type definition (either a bound or a discriminant value) for GNAT_ENTITY, type definition (either a bound or a discriminant value) for GNAT_ENTITY,
return the GCC tree to use for that expression. GNU_NAME is the return the GCC tree to use for that expression. GNU_NAME is the suffix
qualification to use if an external name is appropriate and DEFINITION is to use if a variable needs to be created and DEFINITION is true if this
true if this is a definition of GNAT_ENTITY. If NEED_VALUE is true, we is a definition of GNAT_ENTITY. If NEED_VALUE is true, we need a result;
need a result. Otherwise, we are just elaborating this for side-effects. otherwise, we are just elaborating the expression for side-effects. If
If NEED_DEBUG is true we need the symbol for debugging purposes even if it NEED_DEBUG is true, we need a variable for debugging purposes even if it
isn't needed for code generation. */ isn't needed for code generation. */
static tree static tree
elaborate_expression (Node_Id gnat_expr, Entity_Id gnat_entity, elaborate_expression (Node_Id gnat_expr, Entity_Id gnat_entity, tree gnu_name,
tree gnu_name, bool definition, bool need_value, bool definition, bool need_value, bool need_debug)
bool need_debug)
{ {
tree gnu_expr; tree gnu_expr;
/* If we already elaborated this expression (e.g., it was involved /* If we already elaborated this expression (e.g. it was involved
in the definition of a private type), use the old value. */ in the definition of a private type), use the old value. */
if (present_gnu_tree (gnat_expr)) if (present_gnu_tree (gnat_expr))
return get_gnu_tree (gnat_expr); return get_gnu_tree (gnat_expr);
/* If we don't need a value and this is static or a discriminant, we /* If we don't need a value and this is static or a discriminant,
don't need to do anything. */ we don't need to do anything. */
else if (!need_value if (!need_value
&& (Is_OK_Static_Expression (gnat_expr) && (Is_OK_Static_Expression (gnat_expr)
|| (Nkind (gnat_expr) == N_Identifier || (Nkind (gnat_expr) == N_Identifier
&& Ekind (Entity (gnat_expr)) == E_Discriminant))) && Ekind (Entity (gnat_expr)) == E_Discriminant)))
return 0; return NULL_TREE;
/* If it's a static expression, we don't need a variable for debugging. */
if (need_debug && Is_OK_Static_Expression (gnat_expr))
need_debug = false;
/* Otherwise, convert this tree to its GCC equivalent. */ /* Otherwise, convert this tree to its GCC equivalent and elaborate it. */
gnu_expr gnu_expr = elaborate_expression_1 (gnat_to_gnu (gnat_expr), gnat_entity,
= elaborate_expression_1 (gnat_expr, gnat_entity, gnat_to_gnu (gnat_expr), gnu_name, definition, need_debug);
gnu_name, definition, need_debug);
/* Save the expression in case we try to elaborate this entity again. Since /* Save the expression in case we try to elaborate this entity again. Since
it's not a DECL, don't check it. Don't save if it's a discriminant. */ it's not a DECL, don't check it. Don't save if it's a discriminant. */
...@@ -5657,29 +5654,27 @@ elaborate_expression (Node_Id gnat_expr, Entity_Id gnat_entity, ...@@ -5657,29 +5654,27 @@ elaborate_expression (Node_Id gnat_expr, Entity_Id gnat_entity,
return need_value ? gnu_expr : error_mark_node; return need_value ? gnu_expr : error_mark_node;
} }
/* Similar, but take a GNU expression. */ /* Similar, but take a GNU expression and always return a result. */
static tree static tree
elaborate_expression_1 (Node_Id gnat_expr, Entity_Id gnat_entity, elaborate_expression_1 (tree gnu_expr, Entity_Id gnat_entity, tree gnu_name,
tree gnu_expr, tree gnu_name, bool definition, bool definition, bool need_debug)
bool need_debug)
{ {
tree gnu_decl = NULL_TREE;
/* Skip any conversions and simple arithmetics to see if the expression /* Skip any conversions and simple arithmetics to see if the expression
is a read-only variable. is a read-only variable.
??? This really should remain read-only, but we have to think about ??? This really should remain read-only, but we have to think about
the typing of the tree here. */ the typing of the tree here. */
tree gnu_inner_expr tree gnu_inner_expr
= skip_simple_arithmetic (remove_conversions (gnu_expr, true)); = skip_simple_arithmetic (remove_conversions (gnu_expr, true));
tree gnu_decl = NULL_TREE;
bool expr_global = Is_Public (gnat_entity) || global_bindings_p (); bool expr_global = Is_Public (gnat_entity) || global_bindings_p ();
bool expr_variable; bool expr_variable;
/* In most cases, we won't see a naked FIELD_DECL here because a /* In most cases, we won't see a naked FIELD_DECL because a discriminant
discriminant reference will have been replaced with a COMPONENT_REF reference will have been replaced with a COMPONENT_REF when the type
when the type is being elaborated. However, there are some cases is being elaborated. However, there are some cases involving child
involving child types where we will. So convert it to a COMPONENT_REF types where we will. So convert it to a COMPONENT_REF. We hope it
here. We have to hope it will be at the highest level of the will be at the highest level of the expression in these cases. */
expression in these cases. */
if (TREE_CODE (gnu_expr) == FIELD_DECL) if (TREE_CODE (gnu_expr) == FIELD_DECL)
gnu_expr = build3 (COMPONENT_REF, TREE_TYPE (gnu_expr), gnu_expr = build3 (COMPONENT_REF, TREE_TYPE (gnu_expr),
build0 (PLACEHOLDER_EXPR, DECL_CONTEXT (gnu_expr)), build0 (PLACEHOLDER_EXPR, DECL_CONTEXT (gnu_expr)),
...@@ -5693,19 +5688,14 @@ elaborate_expression_1 (Node_Id gnat_expr, Entity_Id gnat_entity, ...@@ -5693,19 +5688,14 @@ elaborate_expression_1 (Node_Id gnat_expr, Entity_Id gnat_entity,
by the variable; otherwise use a SAVE_EXPR if needed. Note that we by the variable; otherwise use a SAVE_EXPR if needed. Note that we
rely here on the fact that an expression cannot contain both the rely here on the fact that an expression cannot contain both the
discriminant and some other variable. */ discriminant and some other variable. */
expr_variable = (!CONSTANT_CLASS_P (gnu_expr) expr_variable = (!CONSTANT_CLASS_P (gnu_expr)
&& !(TREE_CODE (gnu_inner_expr) == VAR_DECL && !(TREE_CODE (gnu_inner_expr) == VAR_DECL
&& (TREE_READONLY (gnu_inner_expr) && (TREE_READONLY (gnu_inner_expr)
|| DECL_READONLY_ONCE_ELAB (gnu_inner_expr))) || DECL_READONLY_ONCE_ELAB (gnu_inner_expr)))
&& !CONTAINS_PLACEHOLDER_P (gnu_expr)); && !CONTAINS_PLACEHOLDER_P (gnu_expr));
/* If this is a static expression or contains a discriminant, we don't /* If GNU_EXPR contains a discriminant, we can't elaborate a variable. */
need the variable for debugging (and can't elaborate anyway if a if (need_debug && CONTAINS_PLACEHOLDER_P (gnu_expr))
discriminant). */
if (need_debug
&& (Is_OK_Static_Expression (gnat_expr)
|| CONTAINS_PLACEHOLDER_P (gnu_expr)))
need_debug = false; need_debug = false;
/* Now create the variable if we need it. */ /* Now create the variable if we need it. */
...@@ -5721,10 +5711,8 @@ elaborate_expression_1 (Node_Id gnat_expr, Entity_Id gnat_entity, ...@@ -5721,10 +5711,8 @@ elaborate_expression_1 (Node_Id gnat_expr, Entity_Id gnat_entity,
can do the right thing in the local case. */ can do the right thing in the local case. */
if (expr_global && expr_variable) if (expr_global && expr_variable)
return gnu_decl; return gnu_decl;
else if (!expr_variable)
return gnu_expr; return expr_variable ? maybe_variable (gnu_expr) : gnu_expr;
else
return maybe_variable (gnu_expr);
} }
/* Create a record type that contains a SIZE bytes long field of TYPE with a /* Create a record type that contains a SIZE bytes long field of TYPE with a
...@@ -7714,6 +7702,7 @@ substitute_in_type (tree t, tree f, tree r) ...@@ -7714,6 +7702,7 @@ substitute_in_type (tree t, tree f, tree r)
case INTEGER_TYPE: case INTEGER_TYPE:
case ENUMERAL_TYPE: case ENUMERAL_TYPE:
case BOOLEAN_TYPE: case BOOLEAN_TYPE:
case REAL_TYPE:
if (CONTAINS_PLACEHOLDER_P (TYPE_MIN_VALUE (t)) if (CONTAINS_PLACEHOLDER_P (TYPE_MIN_VALUE (t))
|| CONTAINS_PLACEHOLDER_P (TYPE_MAX_VALUE (t))) || CONTAINS_PLACEHOLDER_P (TYPE_MAX_VALUE (t)))
{ {
...@@ -7726,27 +7715,11 @@ substitute_in_type (tree t, tree f, tree r) ...@@ -7726,27 +7715,11 @@ substitute_in_type (tree t, tree f, tree r)
new = copy_type (t); new = copy_type (t);
TYPE_MIN_VALUE (new) = low; TYPE_MIN_VALUE (new) = low;
TYPE_MAX_VALUE (new) = high; TYPE_MAX_VALUE (new) = high;
if (TYPE_INDEX_TYPE (t))
if (TREE_CODE (t) == INTEGER_TYPE && TYPE_INDEX_TYPE (t))
SET_TYPE_INDEX_TYPE SET_TYPE_INDEX_TYPE
(new, substitute_in_type (TYPE_INDEX_TYPE (t), f, r)); (new, substitute_in_type (TYPE_INDEX_TYPE (t), f, r));
return new;
}
return t;
case REAL_TYPE:
if (CONTAINS_PLACEHOLDER_P (TYPE_MIN_VALUE (t))
|| CONTAINS_PLACEHOLDER_P (TYPE_MAX_VALUE (t)))
{
tree low = SUBSTITUTE_IN_EXPR (TYPE_MIN_VALUE (t), f, r);
tree high = SUBSTITUTE_IN_EXPR (TYPE_MAX_VALUE (t), f, r);
if (low == TYPE_MIN_VALUE (t) && high == TYPE_MAX_VALUE (t))
return t;
new = copy_type (t);
TYPE_MIN_VALUE (new) = low;
TYPE_MAX_VALUE (new) = high;
return new; return new;
} }
......
...@@ -7246,30 +7246,29 @@ protect_multiple_eval (tree exp) ...@@ -7246,30 +7246,29 @@ protect_multiple_eval (tree exp)
if (!TREE_SIDE_EFFECTS (exp)) if (!TREE_SIDE_EFFECTS (exp))
return exp; return exp;
/* If it is a conversion, protect what's inside the conversion. /* If this is a conversion, protect what's inside the conversion.
Similarly, if we're indirectly referencing something, we only Similarly, if we're indirectly referencing something, we only
actually need to protect the address since the data itself can't need to protect the address since the data itself can't change
change in these situations. */ in these situations. */
else if (TREE_CODE (exp) == NON_LVALUE_EXPR if (TREE_CODE (exp) == NON_LVALUE_EXPR
|| CONVERT_EXPR_P (exp) || CONVERT_EXPR_P (exp)
|| TREE_CODE (exp) == VIEW_CONVERT_EXPR || TREE_CODE (exp) == VIEW_CONVERT_EXPR
|| TREE_CODE (exp) == INDIRECT_REF || TREE_CODE (exp) == INDIRECT_REF
|| TREE_CODE (exp) == UNCONSTRAINED_ARRAY_REF) || TREE_CODE (exp) == UNCONSTRAINED_ARRAY_REF)
return build1 (TREE_CODE (exp), type, return build1 (TREE_CODE (exp), type,
protect_multiple_eval (TREE_OPERAND (exp, 0))); protect_multiple_eval (TREE_OPERAND (exp, 0)));
/* If EXP is a fat pointer or something that can be placed into a register, /* If this is a fat pointer or something that can be placed into a
just make a SAVE_EXPR. */ register, just make a SAVE_EXPR. */
if (TYPE_FAT_POINTER_P (type) || TYPE_MODE (type) != BLKmode) if (TYPE_FAT_POINTER_P (type) || TYPE_MODE (type) != BLKmode)
return save_expr (exp); return save_expr (exp);
/* Otherwise, dereference, protect the address, and re-reference. */ /* Otherwise, reference, protect the address and dereference. */
else return
return build_unary_op (INDIRECT_REF, type,
build_unary_op (INDIRECT_REF, type, save_expr (build_unary_op (ADDR_EXPR,
save_expr (build_unary_op (ADDR_EXPR, build_reference_type (type),
build_reference_type (type), exp)));
exp)));
} }
/* This is equivalent to stabilize_reference in tree.c, but we know how to /* This is equivalent to stabilize_reference in tree.c, but we know how to
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment