]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - gcc/ada/gcc-interface/misc.c
Wrap option names in gcc internal messages with %< and %>.
[thirdparty/gcc.git] / gcc / ada / gcc-interface / misc.c
index 521f8b99071e740e99d435073c71828d026c2f89..5737165949e470e4d24dc1763f52e6b66411061b 100644 (file)
@@ -6,7 +6,7 @@
  *                                                                          *
  *                           C Implementation File                          *
  *                                                                          *
- *          Copyright (C) 1992-2016, Free Software Foundation, Inc.         *
+ *          Copyright (C) 1992-2019, 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- *
@@ -77,9 +77,6 @@ int optimize;
 #undef optimize_size
 int optimize_size;
 
-#undef flag_compare_debug
-int flag_compare_debug;
-
 #undef flag_short_enums
 int flag_short_enums;
 
@@ -138,8 +135,9 @@ gnat_option_lang_mask (void)
    are marked as Ada-specific.  Return true on success or false on failure.  */
 
 static bool
-gnat_handle_option (size_t scode, const char *arg, int value, int kind,
-                   location_t loc, const struct cl_option_handlers *handlers)
+gnat_handle_option (size_t scode, const char *arg, HOST_WIDE_INT value,
+                   int kind, location_t loc,
+                   const struct cl_option_handlers *handlers)
 {
   enum opt_code code = (enum opt_code) scode;
 
@@ -149,7 +147,7 @@ gnat_handle_option (size_t scode, const char *arg, int value, int kind,
       handle_generated_option (&global_options, &global_options_set,
                               OPT_Wunused, NULL, value,
                               gnat_option_lang_mask (), kind, loc,
-                              handlers, global_dc);
+                              handlers, true, global_dc);
       warn_uninitialized = value;
       warn_maybe_uninitialized = value;
       break;
@@ -168,8 +166,10 @@ gnat_handle_option (size_t scode, const char *arg, int value, int kind,
       /* These are handled by the front-end.  */
       break;
 
+    case OPT_fopenacc:
     case OPT_fshort_enums:
     case OPT_fsigned_char:
+    case OPT_funsigned_char:
       /* These are handled by the middle-end.  */
       break;
 
@@ -255,22 +255,23 @@ static bool
 gnat_post_options (const char **pfilename ATTRIBUTE_UNUSED)
 {
   /* Excess precision other than "fast" requires front-end support.  */
-  if (flag_excess_precision_cmdline == EXCESS_PRECISION_STANDARD
-      && TARGET_FLT_EVAL_METHOD_NON_DEFAULT)
-    sorry ("-fexcess-precision=standard for Ada");
+  if (flag_excess_precision_cmdline == EXCESS_PRECISION_STANDARD)
+    sorry ("%<-fexcess-precision=standard%> for Ada");
   flag_excess_precision_cmdline = EXCESS_PRECISION_FAST;
 
   /* No psABI change warnings for Ada.  */
   warn_psabi = 0;
 
+  /* No return type warnings for Ada.  */
+  warn_return_type = 0;
+
+  /* No string overflow warnings for Ada.  */
+  warn_stringop_overflow = 0;
+
   /* No caret by default for Ada.  */
   if (!global_options_set.x_flag_diagnostics_show_caret)
     global_dc->show_caret = false;
 
-  /* Set strict overflow by default for Ada.  */
-  if (!global_options_set.x_flag_strict_overflow)
-    global_options.x_flag_strict_overflow = true;
-
   /* Warn only if STABS is not the default: we don't want to emit a warning if
      the user did not use a -gstabs option.  */
   if (PREFERRED_DEBUGGING_TYPE != DBX_DEBUG && write_symbols == DBX_DEBUG)
@@ -281,7 +282,6 @@ gnat_post_options (const char **pfilename ATTRIBUTE_UNUSED)
   gnat_encodings = global_options.x_gnat_encodings;
   optimize = global_options.x_optimize;
   optimize_size = global_options.x_optimize_size;
-  flag_compare_debug = global_options.x_flag_compare_debug;
   flag_stack_check = global_options.x_flag_stack_check;
   flag_short_enums = global_options.x_flag_short_enums;
 
@@ -344,7 +344,6 @@ internal_error_function (diagnostic_context *context, const char *msgid,
   sp_loc.Bounds = &temp_loc;
   sp_loc.Array = loc;
 
-  Current_Error_Node = error_gnat_node;
   Compiler_Abort (sp, sp_loc, true);
 }
 
@@ -394,7 +393,7 @@ gnat_init_gcc_eh (void)
   using_eh_for_cleanups ();
 
   /* Turn on -fexceptions, -fnon-call-exceptions and -fdelete-dead-exceptions.
-     The first one triggers the generation of the necessary exception tables.
+     The first one activates the support for exceptions in the compiler.
      The second one is useful for two reasons: 1/ we map some asynchronous
      signals like SEGV to exceptions, so we need to ensure that the insns
      which can lead to such signals are correctly attached to the exception
@@ -404,10 +403,26 @@ gnat_init_gcc_eh (void)
      for such calls to actually raise in Ada.
      The third one is an optimization that makes it possible to delete dead
      instructions that may throw exceptions, most notably loads and stores,
-     as permitted in Ada.  */
+     as permitted in Ada.
+     Turn off -faggressive-loop-optimizations because it may optimize away
+     out-of-bound array accesses that we want to be able to catch.
+     If checks are disabled, we use the same settings as the C++ compiler,
+     except for the runtime on platforms where S'Machine_Overflow is true
+     because the runtime depends on FP (hardware) checks being properly
+     handled despite being compiled in -gnatp mode.  */
   flag_exceptions = 1;
-  flag_non_call_exceptions = 1;
   flag_delete_dead_exceptions = 1;
+  if (Suppress_Checks)
+    {
+      if (!global_options_set.x_flag_non_call_exceptions)
+       flag_non_call_exceptions = Machine_Overflows_On_Target && GNAT_Mode;
+    }
+  else
+    {
+      flag_non_call_exceptions = 1;
+      flag_aggressive_loop_optimizations = 0;
+      warn_aggressive_loop_optimizations = 0;
+    }
 
   init_eh ();
 }
@@ -471,6 +486,7 @@ gnat_print_type (FILE *file, tree node, int indent)
   switch (TREE_CODE (node))
     {
     case FUNCTION_TYPE:
+    case METHOD_TYPE:
       print_node (file, "ci/co list", TYPE_CI_CO_LIST (node), indent + 4);
       break;
 
@@ -682,12 +698,12 @@ gnat_get_fixed_point_type_info (const_tree type,
 
 /* Return true if types T1 and T2 are identical for type hashing purposes.
    Called only after doing all language independent checks.  At present,
-   this function is only called when both types are FUNCTION_TYPE.  */
+   this is only called when both types are FUNCTION_TYPE or METHOD_TYPE.  */
 
 static bool
 gnat_type_hash_eq (const_tree t1, const_tree t2)
 {
-  gcc_assert (TREE_CODE (t1) == FUNCTION_TYPE);
+  gcc_assert (FUNC_OR_METHOD_TYPE_P (t1) && TREE_CODE (t1) == TREE_CODE (t2));
   return fntype_same_flags_p (t1, TYPE_CI_CO_LIST (t2),
                              TYPE_RETURN_UNCONSTRAINED_P (t2),
                              TYPE_RETURN_BY_DIRECT_REF_P (t2),
@@ -711,6 +727,10 @@ gnat_get_alias_set (tree type)
   if (TYPE_IS_PADDING_P (type))
     return get_alias_set (TREE_TYPE (TYPE_FIELDS (type)));
 
+  /* If this is an extra subtype, use the base type.  */
+  else if (TYPE_IS_EXTRA_SUBTYPE_P (type))
+    return get_alias_set (get_base_type (type));
+
   /* If the type is an unconstrained array, use the type of the
      self-referential array we make.  */
   else if (TREE_CODE (type) == UNCONSTRAINED_ARRAY_TYPE)
@@ -718,7 +738,9 @@ gnat_get_alias_set (tree type)
       get_alias_set (TREE_TYPE (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (type)))));
 
   /* If the type can alias any other types, return the alias set 0.  */
-  else if (TYPE_P (type) && TYPE_UNIVERSAL_ALIASING_P (type))
+  else if (TYPE_P (type)
+          && !TYPE_IS_DUMMY_P (type)
+          && TYPE_UNIVERSAL_ALIASING_P (type))
     return 0;
 
   return -1;
@@ -733,27 +755,27 @@ gnat_type_max_size (const_tree gnu_type)
   /* First see what we can get from TYPE_SIZE_UNIT, which might not
      be constant even for simple expressions if it has already been
      elaborated and possibly replaced by a VAR_DECL.  */
-  tree max_unitsize = max_size (TYPE_SIZE_UNIT (gnu_type), true);
+  tree max_size_unit = max_size (TYPE_SIZE_UNIT (gnu_type), true);
 
   /* If we don't have a constant, see what we can get from TYPE_ADA_SIZE,
      which should stay untouched.  */
-  if (!tree_fits_uhwi_p (max_unitsize)
+  if (!tree_fits_uhwi_p (max_size_unit)
       && RECORD_OR_UNION_TYPE_P (gnu_type)
       && !TYPE_FAT_POINTER_P (gnu_type)
       && TYPE_ADA_SIZE (gnu_type))
     {
-      tree max_adasize = max_size (TYPE_ADA_SIZE (gnu_type), true);
+      tree max_ada_size = max_size (TYPE_ADA_SIZE (gnu_type), true);
 
       /* If we have succeeded in finding a constant, round it up to the
         type's alignment and return the result in units.  */
-      if (tree_fits_uhwi_p (max_adasize))
-       max_unitsize
+      if (tree_fits_uhwi_p (max_ada_size))
+       max_size_unit
          = size_binop (CEIL_DIV_EXPR,
-                       round_up (max_adasize, TYPE_ALIGN (gnu_type)),
+                       round_up (max_ada_size, TYPE_ALIGN (gnu_type)),
                        bitsize_unit_node);
     }
 
-  return max_unitsize;
+  return max_size_unit;
 }
 
 static tree get_array_bit_stride (tree);
@@ -897,6 +919,7 @@ gnat_get_array_descr_info (const_tree const_type,
     }
 
   info->ndimensions = i;
+  info->rank = NULL_TREE;
 
   /* Too many dimensions?  Give up generating proper description: yield instead
      nested arrays.  Note that in this case, this hook is invoked once on each
@@ -915,7 +938,7 @@ gnat_get_array_descr_info (const_tree const_type,
      structure.  */
   for (i = (convention_fortran_p ? info->ndimensions - 1 : 0),
        dimen = first_dimen;
-       0 <= i && i < info->ndimensions;
+       IN_RANGE (i, 0, info->ndimensions - 1);
        i += (convention_fortran_p ? -1 : 1),
        dimen = TREE_TYPE (dimen))
     {
@@ -932,7 +955,7 @@ gnat_get_array_descr_info (const_tree const_type,
             and XUA types.  */
          if (TYPE_CONTEXT (first_dimen)
              && TREE_CODE (TYPE_CONTEXT (first_dimen)) != RECORD_TYPE
-             && contains_placeholder_p (TYPE_MIN_VALUE (index_type))
+             && CONTAINS_PLACEHOLDER_P (TYPE_MIN_VALUE (index_type))
              && gnat_encodings != DWARF_GNAT_ENCODINGS_MINIMAL)
            {
              info->dimen[i].lower_bound = NULL_TREE;
@@ -1106,16 +1129,16 @@ default_pass_by_ref (tree gnu_type)
      is an In Out parameter, but it's probably best to err on the side of
      passing more things by reference.  */
 
-  if (pass_by_reference (NULL, TYPE_MODE (gnu_type), gnu_type, true))
+  if (AGGREGATE_TYPE_P (gnu_type)
+      && (!valid_constant_size_p (TYPE_SIZE_UNIT (gnu_type))
+         || compare_tree_int (TYPE_SIZE_UNIT (gnu_type),
+                              TYPE_ALIGN (gnu_type)) > 0))
     return true;
 
-  if (targetm.calls.return_in_memory (gnu_type, NULL_TREE))
+  if (pass_by_reference (NULL, TYPE_MODE (gnu_type), gnu_type, true))
     return true;
 
-  if (AGGREGATE_TYPE_P (gnu_type)
-      && (!valid_constant_size_p (TYPE_SIZE_UNIT (gnu_type))
-         || 0 < compare_tree_int (TYPE_SIZE_UNIT (gnu_type),
-                                  TYPE_ALIGN (gnu_type))))
+  if (targetm.calls.return_in_memory (gnu_type, NULL_TREE))
     return true;
 
   return false;
@@ -1263,11 +1286,14 @@ enumerate_modes (void (*f) (const char *, int, int, int, int, int, int, int))
          }
 
       /* If no predefined C types were found, register the mode itself.  */
-      if (!skip_p)
+      int nunits, precision, bitsize;
+      if (!skip_p
+         && GET_MODE_NUNITS (i).is_constant (&nunits)
+         && GET_MODE_PRECISION (i).is_constant (&precision)
+         && GET_MODE_BITSIZE (i).is_constant (&bitsize))
        f (GET_MODE_NAME (i), digs, complex_p,
-          vector_p ? GET_MODE_NUNITS (i) : 0, float_rep,
-          GET_MODE_PRECISION (i), GET_MODE_BITSIZE (i),
-          GET_MODE_ALIGNMENT (i));
+          vector_p ? nunits : 0, float_rep,
+          precision, bitsize, GET_MODE_ALIGNMENT (i));
     }
 }
 
@@ -1276,12 +1302,14 @@ enumerate_modes (void (*f) (const char *, int, int, int, int, int, int, int))
 int
 fp_prec_to_size (int prec)
 {
-  machine_mode mode;
+  opt_scalar_float_mode opt_mode;
 
-  for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT); mode != VOIDmode;
-       mode = GET_MODE_WIDER_MODE (mode))
-    if (GET_MODE_PRECISION (mode) == prec)
-      return GET_MODE_BITSIZE (mode);
+  FOR_EACH_MODE_IN_CLASS (opt_mode, MODE_FLOAT)
+    {
+      scalar_float_mode mode = opt_mode.require ();
+      if (GET_MODE_PRECISION (mode) == prec)
+       return GET_MODE_BITSIZE (mode);
+    }
 
   gcc_unreachable ();
 }
@@ -1291,12 +1319,14 @@ fp_prec_to_size (int prec)
 int
 fp_size_to_prec (int size)
 {
-  machine_mode mode;
+  opt_scalar_float_mode opt_mode;
 
-  for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT); mode != VOIDmode;
-       mode = GET_MODE_WIDER_MODE (mode))
-    if (GET_MODE_BITSIZE (mode) == size)
-      return GET_MODE_PRECISION (mode);
+  FOR_EACH_MODE_IN_CLASS (opt_mode, MODE_FLOAT)
+    {
+      scalar_mode mode = opt_mode.require ();
+      if (GET_MODE_BITSIZE (mode) == size)
+       return GET_MODE_PRECISION (mode);
+    }
 
   gcc_unreachable ();
 }
@@ -1331,6 +1361,23 @@ gnat_init_ts (void)
   MARK_TS_TYPED (EXIT_STMT);
 }
 
+/* Return the size of a tree with CODE, which is a language-specific tree code
+   in category tcc_constant, tcc_exceptional or tcc_type.  The default expects
+   never to be called.  */
+
+static size_t
+gnat_tree_size (enum tree_code code)
+{
+  gcc_checking_assert (code >= NUM_TREE_CODES);
+  switch (code)
+    {
+    case UNCONSTRAINED_ARRAY_TYPE:
+      return sizeof (tree_type_non_common);
+    default:
+      gcc_unreachable ();
+    }
+}
+
 /* Return the lang specific structure attached to NODE.  Allocate it (cleared)
    if needed.  */
 
@@ -1348,6 +1395,8 @@ get_lang_specific (tree node)
 #define LANG_HOOKS_NAME                        "GNU Ada"
 #undef  LANG_HOOKS_IDENTIFIER_SIZE
 #define LANG_HOOKS_IDENTIFIER_SIZE     sizeof (struct tree_identifier)
+#undef  LANG_HOOKS_TREE_SIZE
+#define LANG_HOOKS_TREE_SIZE           gnat_tree_size
 #undef  LANG_HOOKS_INIT
 #define LANG_HOOKS_INIT                        gnat_init
 #undef  LANG_HOOKS_OPTION_LANG_MASK
@@ -1365,9 +1414,11 @@ get_lang_specific (tree node)
 #undef  LANG_HOOKS_TYPE_HASH_EQ
 #define LANG_HOOKS_TYPE_HASH_EQ                gnat_type_hash_eq
 #undef  LANG_HOOKS_GETDECLS
-#define LANG_HOOKS_GETDECLS            lhd_return_null_tree_v
+#define LANG_HOOKS_GETDECLS            hook_tree_void_null
 #undef  LANG_HOOKS_PUSHDECL
 #define LANG_HOOKS_PUSHDECL            gnat_return_tree
+#undef  LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL
+#define LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL hook_bool_const_tree_false
 #undef  LANG_HOOKS_GET_ALIAS_SET
 #define LANG_HOOKS_GET_ALIAS_SET       gnat_get_alias_set
 #undef  LANG_HOOKS_PRINT_DECL
@@ -1401,20 +1452,19 @@ get_lang_specific (tree node)
 #undef  LANG_HOOKS_GET_DEBUG_TYPE
 #define LANG_HOOKS_GET_DEBUG_TYPE      gnat_get_debug_type
 #undef  LANG_HOOKS_GET_FIXED_POINT_TYPE_INFO
-#define LANG_HOOKS_GET_FIXED_POINT_TYPE_INFO \
-                                       gnat_get_fixed_point_type_info
+#define LANG_HOOKS_GET_FIXED_POINT_TYPE_INFO gnat_get_fixed_point_type_info
 #undef  LANG_HOOKS_ATTRIBUTE_TABLE
 #define LANG_HOOKS_ATTRIBUTE_TABLE     gnat_internal_attribute_table
 #undef  LANG_HOOKS_BUILTIN_FUNCTION
 #define LANG_HOOKS_BUILTIN_FUNCTION    gnat_builtin_function
+#undef  LANG_HOOKS_INIT_TS
+#define LANG_HOOKS_INIT_TS             gnat_init_ts
 #undef  LANG_HOOKS_EH_PERSONALITY
 #define LANG_HOOKS_EH_PERSONALITY      gnat_eh_personality
 #undef  LANG_HOOKS_DEEP_UNSHARING
 #define LANG_HOOKS_DEEP_UNSHARING      true
-#undef  LANG_HOOKS_INIT_TS
-#define LANG_HOOKS_INIT_TS             gnat_init_ts
-#undef  LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL
-#define LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL hook_bool_const_tree_false
+#undef  LANG_HOOKS_CUSTOM_FUNCTION_DESCRIPTORS
+#define LANG_HOOKS_CUSTOM_FUNCTION_DESCRIPTORS true
 
 struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;