Fix PR gdb/20948: --write option to GDB causes segmentation fault
[deliverable/binutils-gdb.git] / gdb / ada-lang.c
index b34efa919ea356d57f4c2fd5dbc9afa960b6edb4..1462271a710bb88e18dbd1846baef803c4469c16 100644 (file)
@@ -541,17 +541,12 @@ ada_unqualified_name (const char *decoded_name)
   return result;
 }
 
-/* Return a string starting with '<', followed by STR, and '>'.
-   The result is good until the next call.  */
+/* Return a string starting with '<', followed by STR, and '>'.  */
 
-static char *
+static std::string
 add_angle_brackets (const char *str)
 {
-  static char *result = NULL;
-
-  xfree (result);
-  result = xstrprintf ("<%s>", str);
-  return result;
+  return string_printf ("<%s>", str);
 }
 
 static const char *
@@ -1169,6 +1164,11 @@ ada_decode (const char *encoded)
   static char *decoding_buffer = NULL;
   static size_t decoding_buffer_size = 0;
 
+  /* With function descriptors on PPC64, the value of a symbol named
+     ".FN", if it exists, is the entry point of the function "FN".  */
+  if (encoded[0] == '.')
+    encoded += 1;
+
   /* The name of the Ada main procedure starts with "_ada_".
      This prefix is not part of the decoded name, so skip this part
      if we see this prefix.  */
@@ -2814,17 +2814,33 @@ value_assign_to_component (struct value *container, struct value *component,
     bits = value_bitsize (component);
 
   if (gdbarch_bits_big_endian (get_type_arch (value_type (container))))
-    move_bits (value_contents_writeable (container) + offset_in_container,
-              value_bitpos (container) + bit_offset_in_container,
-              value_contents (val),
-              TYPE_LENGTH (value_type (component)) * TARGET_CHAR_BIT - bits,
-              bits, 1);
+    {
+      int src_offset;
+
+      if (is_scalar_type (check_typedef (value_type (component))))
+        src_offset
+         = TYPE_LENGTH (value_type (component)) * TARGET_CHAR_BIT - bits;
+      else
+       src_offset = 0;
+      move_bits (value_contents_writeable (container) + offset_in_container,
+                value_bitpos (container) + bit_offset_in_container,
+                value_contents (val), src_offset, bits, 1);
+    }
   else
     move_bits (value_contents_writeable (container) + offset_in_container,
               value_bitpos (container) + bit_offset_in_container,
               value_contents (val), 0, bits, 0);
 }
 
+/* Determine if TYPE is an access to an unconstrained array.  */
+
+bool
+ada_is_access_to_unconstrained_array (struct type *type)
+{
+  return (TYPE_CODE (type) == TYPE_CODE_TYPEDEF
+         && is_thick_pntr (ada_typedef_target_type (type)));
+}
+
 /* The value of the element of array ARR at the ARITY indices given in IND.
    ARR may be either a simple array, GNAT array descriptor, or pointer
    thereto.  */
@@ -2845,10 +2861,34 @@ ada_value_subscript (struct value *arr, int arity, struct value **ind)
 
   for (k = 0; k < arity; k += 1)
     {
+      struct type *saved_elt_type = TYPE_TARGET_TYPE (elt_type);
+
       if (TYPE_CODE (elt_type) != TYPE_CODE_ARRAY)
         error (_("too many subscripts (%d expected)"), k);
+
       elt = value_subscript (elt, pos_atr (ind[k]));
+
+      if (ada_is_access_to_unconstrained_array (saved_elt_type)
+         && TYPE_CODE (value_type (elt)) != TYPE_CODE_TYPEDEF)
+       {
+         /* The element is a typedef to an unconstrained array,
+            except that the value_subscript call stripped the
+            typedef layer.  The typedef layer is GNAT's way to
+            specify that the element is, at the source level, an
+            access to the unconstrained array, rather than the
+            unconstrained array.  So, we need to restore that
+            typedef layer, which we can do by forcing the element's
+            type back to its original type. Otherwise, the returned
+            value is going to be printed as the array, rather
+            than as an access.  Another symptom of the same issue
+            would be that an expression trying to dereference the
+            element would also be improperly rejected.  */
+         deprecated_set_value_type (elt, saved_elt_type);
+       }
+
+      elt_type = ada_check_typedef (value_type (elt));
     }
+
   return elt;
 }
 
@@ -3508,7 +3548,7 @@ resolve_subexp (expression_up *expp, int *pos, int deprocedure_p,
           && (TYPE_CODE (SYMBOL_TYPE (exp->elts[pc + 2].symbol))
               == TYPE_CODE_FUNC))
         {
-          replace_operator_with_call (expp, pc, 0, 0,
+          replace_operator_with_call (expp, pc, 0, 4,
                                       exp->elts[pc + 2].symbol,
                                       exp->elts[pc + 1].block);
           exp = expp->get ();
@@ -4041,7 +4081,7 @@ get_selections (int *choices, int n_choices, int max_results,
   if (prompt == NULL)
     prompt = "> ";
 
-  args = command_line_input (prompt, 0, annotation_suffix);
+  args = command_line_input (prompt, annotation_suffix);
 
   if (args == NULL)
     error_no_arg (_("one or more choice numbers"));
@@ -5205,8 +5245,6 @@ is_package_name (const char *name)
      to NAME not existing in our list of symbols.  There is only one
      small complication with library-level functions (see below).  */
 
-  char *fun_name;
-
   /* If it is a function that has not been defined at library level,
      then we should be able to look it up in the symbols.  */
   if (standard_lookup (name, NULL, VAR_DOMAIN) != NULL)
@@ -5220,9 +5258,9 @@ is_package_name (const char *name)
   if (strstr (name, "__") != NULL)
     return 0;
 
-  fun_name = xstrprintf ("_ada_%s", name);
+  std::string fun_name = string_printf ("_ada_%s", name);
 
-  return (standard_lookup (fun_name, NULL, VAR_DOMAIN) == NULL);
+  return (standard_lookup (fun_name.c_str (), NULL, VAR_DOMAIN) == NULL);
 }
 
 /* Return nonzero if SYM corresponds to a renaming entity that is
@@ -5786,7 +5824,6 @@ ada_lookup_symbol_list_worker (const lookup_name_info &lookup_name,
 {
   int syms_from_global_search;
   int ndefns;
-  int results_size;
   auto_obstack obstack;
 
   ada_add_all_symbols (&obstack, block, lookup_name,
@@ -5844,7 +5881,7 @@ ada_iterate_over_symbols
 
   for (i = 0; i < ndefs; ++i)
     {
-      if (!callback (results[i].symbol))
+      if (!callback (&results[i]))
        break;
     }
 }
@@ -7517,6 +7554,7 @@ ada_value_struct_elt (struct value *arg, const char *name, int no_err)
 {
   struct type *t, *t1;
   struct value *v;
+  int check_tag;
 
   v = NULL;
   t1 = t = ada_check_typedef (value_type (arg));
@@ -7580,12 +7618,17 @@ ada_value_struct_elt (struct value *arg, const char *name, int no_err)
           if (!find_struct_field (name, t1, 0,
                                   &field_type, &byte_offset, &bit_offset,
                                   &bit_size, NULL))
-           t1 = ada_to_fixed_type (ada_get_base_type (t1), NULL,
-                                    address, NULL, 1);
+           check_tag = 1;
+         else
+           check_tag = 0;
         }
       else
-        t1 = ada_to_fixed_type (ada_get_base_type (t1), NULL,
-                                address, NULL, 1);
+       check_tag = 0;
+
+      /* Convert to fixed type in all cases, so that we have proper
+        offsets to each field in unconstrained record types.  */
+      t1 = ada_to_fixed_type (ada_get_base_type (t1), NULL,
+                             address, NULL, check_tag);
 
       if (find_struct_field (name, t1, 0,
                              &field_type, &byte_offset, &bit_offset,
@@ -9241,13 +9284,13 @@ ada_check_typedef (struct type *type)
   if (type == NULL)
     return NULL;
 
-  /* If our type is a typedef type of a fat pointer, then we're done.
+  /* If our type is an access to an unconstrained array, which is encoded
+     as a TYPE_CODE_TYPEDEF of a fat pointer, then we're done.
      We don't want to strip the TYPE_CODE_TYPDEF layer, because this is
      what allows us to distinguish between fat pointers that represent
      array types, and fat pointers that represent array access types
      (in both cases, the compiler implements them as fat pointers).  */
-  if (TYPE_CODE (type) == TYPE_CODE_TYPEDEF
-      && is_thick_pntr (ada_typedef_target_type (type)))
+  if (ada_is_access_to_unconstrained_array (type))
     return type;
 
   type = check_typedef (type);
@@ -9308,9 +9351,7 @@ struct value *
 ada_to_fixed_value (struct value *val)
 {
   val = unwrap_value (val);
-  val = ada_to_fixed_value_create (value_type (val),
-                                     value_address (val),
-                                     val);
+  val = ada_to_fixed_value_create (value_type (val), value_address (val), val);
   return val;
 }
 \f
@@ -10231,7 +10272,7 @@ ada_value_cast (struct type *type, struct value *arg2)
     return arg2;
 
   if (ada_is_fixed_point_type (type))
-    return (cast_to_fixed (type, arg2));
+    return cast_to_fixed (type, arg2);
 
   if (ada_is_fixed_point_type (value_type (arg2)))
     return cast_from_fixed (type, arg2);
@@ -12108,7 +12149,7 @@ ada_exception_support_info_sniffer (void)
      loaded.  If it is not started, this may mean that the symbol is
      in a shared library.  */
 
-  if (ptid_get_pid (inferior_ptid) == 0)
+  if (inferior_ptid.pid () == 0)
     error (_("Unable to insert catchpoint. Try to start the program first."));
 
   /* At this point, we know that we are debugging an Ada program and
@@ -12243,8 +12284,8 @@ ada_unhandled_exception_name_addr_from_raise (void)
           if (strcmp (func_name.get (),
                      data->exception_info->catch_exception_sym) == 0)
            break; /* We found the frame we were looking for...  */
-         fi = get_prev_frame (fi);
        }
+      fi = get_prev_frame (fi);
     }
 
   if (fi == NULL)
@@ -13216,14 +13257,11 @@ ada_exception_sal (enum ada_exception_catchpoint_kind ex,
   sym_name = ada_exception_sym_name (ex);
   sym = standard_lookup (sym_name, NULL, VAR_DOMAIN);
 
-  /* We can assume that SYM is not NULL at this stage.  If the symbol
-     did not exist, ada_exception_support_info_sniffer would have
-     raised an exception.
+  if (sym == NULL)
+    error (_("Catchpoint symbol not found: %s"), sym_name);
 
-     Also, ada_exception_support_info_sniffer should have already
-     verified that SYM is a function symbol.  */
-  gdb_assert (sym != NULL);
-  gdb_assert (SYMBOL_CLASS (sym) == LOC_BLOCK);
+  if (SYMBOL_CLASS (sym) != LOC_BLOCK)
+    error (_("Unable to insert catchpoint. %s is not a function."), sym_name);
 
   /* Set ADDR_STRING.  */
   *addr_string = xstrdup (sym_name);
@@ -14360,7 +14398,6 @@ extern const struct language_defn ada_language_defn = {
   ada_extensions,
   &ada_exp_descriptor,
   parse,
-  ada_yyerror,
   resolve,
   ada_printchar,                /* Print a character constant */
   ada_printstr,                 /* Function to print string constant */
This page took 0.028565 seconds and 4 git commands to generate.