/* C-compiler utilities for types and variables storage layout
- Copyright (C) 1987-2018 Free Software Foundation, Inc.
+ Copyright (C) 1987-2019 Free Software Foundation, Inc.
This file is part of GCC.
case MODE_VECTOR_ACCUM:
case MODE_VECTOR_UFRACT:
case MODE_VECTOR_UACCUM:
- case MODE_POINTER_BOUNDS:
return int_mode_for_size (GET_MODE_BITSIZE (mode), 0);
case MODE_RANDOM:
DECL_SIZE_UNIT (decl) = variable_size (DECL_SIZE_UNIT (decl));
/* If requested, warn about definitions of large data objects. */
- if ((code == VAR_DECL || code == PARM_DECL)
- && ! DECL_EXTERNAL (decl))
+ if ((code == PARM_DECL || (code == VAR_DECL && !DECL_NONLOCAL_FRAME (decl)))
+ && !DECL_EXTERNAL (decl))
{
tree size = DECL_SIZE_UNIT (decl);
- if (size != 0 && TREE_CODE (size) == INTEGER_CST
- && compare_tree_int (size, warn_larger_than_size) > 0)
+ if (size != 0 && TREE_CODE (size) == INTEGER_CST)
{
- unsigned HOST_WIDE_INT uhwisize = tree_to_uhwi (size);
-
- warning (OPT_Wlarger_than_, "size of %q+D %wu bytes exceeds "
- "maximum object size %wu",
- decl, uhwisize, warn_larger_than_size);
+ /* -Wlarger-than= argument of HOST_WIDE_INT_MAX is treated
+ as if PTRDIFF_MAX had been specified, with the value
+ being that on the target rather than the host. */
+ unsigned HOST_WIDE_INT max_size = warn_larger_than_size;
+ if (max_size == HOST_WIDE_INT_MAX)
+ max_size = tree_to_shwi (TYPE_MAX_VALUE (ptrdiff_type_node));
+
+ if (compare_tree_int (size, max_size) > 0)
+ warning (OPT_Wlarger_than_, "size of %q+D %E bytes exceeds "
+ "maximum object size %wu",
+ decl, size, max_size);
}
}
{
rli->bitpos = size_binop (PLUS_EXPR, rli->bitpos, DECL_SIZE (field));
- /* If we ended a bitfield before the full length of the type then
- pad the struct out to the full length of the last type. */
- if ((DECL_CHAIN (field) == NULL
- || TREE_CODE (DECL_CHAIN (field)) != FIELD_DECL)
- && DECL_BIT_FIELD_TYPE (field)
+ /* If FIELD is the last field and doesn't end at the full length
+ of the type then pad the struct out to the full length of the
+ last type. */
+ if (DECL_BIT_FIELD_TYPE (field)
&& !integer_zerop (DECL_SIZE (field)))
- rli->bitpos = size_binop (PLUS_EXPR, rli->bitpos,
- bitsize_int (rli->remaining_in_alignment));
+ {
+ /* We have to scan, because non-field DECLS are also here. */
+ tree probe = field;
+ while ((probe = DECL_CHAIN (probe)))
+ if (TREE_CODE (probe) == FIELD_DECL)
+ break;
+ if (!probe)
+ rli->bitpos = size_binop (PLUS_EXPR, rli->bitpos,
+ bitsize_int (rli->remaining_in_alignment));
+ }
normalize_rli (rli);
}
/* If this field is the whole struct, remember its mode so
that, say, we can put a double in a class into a DF
register instead of forcing it to live in the stack. */
- if (simple_cst_equal (TYPE_SIZE (type), DECL_SIZE (field)))
+ if (simple_cst_equal (TYPE_SIZE (type), DECL_SIZE (field))
+ /* Partial int types (e.g. __int20) may have TYPE_SIZE equal to
+ wider types (e.g. int32), despite precision being less. Ensure
+ that the TYPE_MODE of the struct does not get set to the partial
+ int mode if there is a wider type also in the struct. */
+ && known_gt (GET_MODE_PRECISION (DECL_MODE (field)),
+ GET_MODE_PRECISION (mode)))
mode = DECL_MODE (field);
/* With some targets, it is sub-optimal to access an aligned
}
/* If we only have one real field; use its mode if that mode's size
- matches the type's size. This only applies to RECORD_TYPE. This
- does not apply to unions. */
+ matches the type's size. This generally only applies to RECORD_TYPE.
+ For UNION_TYPE, if the widest field is MODE_INT then use that mode.
+ If the widest field is MODE_PARTIAL_INT, and the union will be passed
+ by reference, then use that mode. */
poly_uint64 type_size;
- if (TREE_CODE (type) == RECORD_TYPE
+ if ((TREE_CODE (type) == RECORD_TYPE
+ || (TREE_CODE (type) == UNION_TYPE
+ && (GET_MODE_CLASS (mode) == MODE_INT
+ || (GET_MODE_CLASS (mode) == MODE_PARTIAL_INT
+ && targetm.calls.pass_by_reference (pack_cumulative_args (0),
+ mode, type, 0)))))
&& mode != VOIDmode
&& poly_int_tree_p (TYPE_SIZE (type), &type_size)
&& known_eq (GET_MODE_BITSIZE (mode), type_size))