coarray_data_1.f90: Link against libatomic if target libatomic_available.
[gcc.git] / gcc / stor-layout.c
index cb377ca5b82823eeb3c087a3f926cced2e431fba..5d6f2e0166cee4da93235c66dd0d3dfdeefff5a6 100644 (file)
@@ -1,5 +1,5 @@
 /* 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.
 
@@ -390,7 +390,6 @@ int_mode_for_mode (machine_mode mode)
     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:
@@ -756,19 +755,24 @@ layout_decl (tree decl, unsigned int known_align)
     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);
        }
     }
 
@@ -1682,14 +1686,21 @@ place_field (record_layout_info rli, tree field)
     {
       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);
     }
@@ -1823,7 +1834,13 @@ compute_record_mode (tree type)
       /* 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
@@ -1833,10 +1850,17 @@ compute_record_mode (tree type)
     }
 
   /* 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))