* *
* C Implementation File *
* *
- * Copyright (C) 1992-2012, Free Software Foundation, Inc. *
+ * Copyright (C) 1992-2013, 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- *
(build_qualified_type (void_type_node, TYPE_QUAL_VOLATILE));
tree mem_model = build_int_cst (integer_type_node, MEMMODEL_SEQ_CST);
tree orig_src = src;
- tree type = TREE_TYPE (src);
- tree t, val;
+ tree t, addr, val;
unsigned int size;
int fncode;
+ /* Remove conversions to get the address of the underlying object. */
src = remove_conversions (src, false);
size = resolve_atomic_size (TREE_TYPE (src));
if (size == 0)
fncode = (int) BUILT_IN_ATOMIC_LOAD_N + exact_log2 (size) + 1;
t = builtin_decl_implicit ((enum built_in_function) fncode);
- src = build_unary_op (ADDR_EXPR, ptr_type, src);
- val = build_call_expr (t, 2, src, mem_model);
+ addr = build_unary_op (ADDR_EXPR, ptr_type, src);
+ val = build_call_expr (t, 2, addr, mem_model);
- return unchecked_convert (type, val, true);
+ /* First reinterpret the loaded bits in the original type of the load,
+ then convert to the expected result type. */
+ t = fold_build1 (VIEW_CONVERT_EXPR, TREE_TYPE (src), val);
+ return convert (TREE_TYPE (orig_src), t);
}
/* Build an atomic store from SRC to the underlying atomic object in DEST. */
(build_qualified_type (void_type_node, TYPE_QUAL_VOLATILE));
tree mem_model = build_int_cst (integer_type_node, MEMMODEL_SEQ_CST);
tree orig_dest = dest;
- tree t, int_type;
+ tree t, int_type, addr;
unsigned int size;
int fncode;
+ /* Remove conversions to get the address of the underlying object. */
dest = remove_conversions (dest, false);
size = resolve_atomic_size (TREE_TYPE (dest));
if (size == 0)
t = builtin_decl_implicit ((enum built_in_function) fncode);
int_type = gnat_type_for_size (BITS_PER_UNIT * size, 1);
- dest = build_unary_op (ADDR_EXPR, ptr_type, dest);
- src = unchecked_convert (int_type, src, true);
+ /* First convert the bits to be stored to the original type of the store,
+ then reinterpret them in the effective type. But if the original type
+ is a padded type with the same size, convert to the inner type instead,
+ as we don't want to artificially introduce a CONSTRUCTOR here. */
+ if (TYPE_IS_PADDING_P (TREE_TYPE (dest))
+ && TYPE_SIZE (TREE_TYPE (dest))
+ == TYPE_SIZE (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (dest)))))
+ src = convert (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (dest))), src);
+ else
+ src = convert (TREE_TYPE (dest), src);
+ src = fold_build1 (VIEW_CONVERT_EXPR, int_type, src);
+ addr = build_unary_op (ADDR_EXPR, ptr_type, dest);
- return build_call_expr (t, 3, dest, src, mem_model);
+ return build_call_expr (t, 3, addr, src, mem_model);
}
\f
/* Make a binary operation of kind OP_CODE. RESULT_TYPE is the type
v->qsort (compare_elmt_bitpos);
result = build_constructor (type, v);
+ CONSTRUCTOR_NO_CLEARING (result) = 1;
TREE_CONSTANT (result) = TREE_STATIC (result) = allconstant;
TREE_SIDE_EFFECTS (result) = side_effects;
TREE_READONLY (result) = TYPE_READONLY (type) || allconstant;
{
tree new_field;
- /* First loop thru normal components. */
+ /* First loop through normal components. */
for (new_field = TYPE_FIELDS (record_type);
new_field;
new_field = DECL_CHAIN (new_field))
break;
/* Next, see if we're looking for an inherited component in an extension.
- If so, look thru the extension directly, but not if the type contains
+ If so, look through the extension directly, but not if the type contains
a placeholder, as it might be needed for a later substitution. */
if (!new_field
&& TREE_CODE (record_variable) == VIEW_CONVERT_EXPR
return ref;
}
- /* Next, loop thru DECL_INTERNAL_P components if we haven't found the
+ /* Next, loop through DECL_INTERNAL_P components if we haven't found the
component in the first search. Doing this search in two steps is
required to avoid hidden homonymous fields in the _Parent field. */
if (!new_field)
= ((data_align > system_allocator_alignment)
? make_aligning_type (data_type, data_align, data_size,
system_allocator_alignment,
- POINTER_SIZE / BITS_PER_UNIT)
+ POINTER_SIZE / BITS_PER_UNIT,
+ gnat_node)
: NULL_TREE);
tree size_to_malloc
init);
/* If the size overflows, pass -1 so Storage_Error will be raised. */
- if (TREE_CODE (size) == INTEGER_CST && TREE_OVERFLOW (size))
+ if (TREE_CODE (size) == INTEGER_CST && !valid_constant_size_p (size))
size = size_int (-1);
storage = build_call_alloc_dealloc (NULL_TREE, size, storage_type,
}
/* If the size overflows, pass -1 so Storage_Error will be raised. */
- if (TREE_CODE (size) == INTEGER_CST && TREE_OVERFLOW (size))
+ if (TREE_CODE (size) == INTEGER_CST && !valid_constant_size_p (size))
size = size_int (-1);
storage = convert (result_type,