This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: RFC: fix `gdb -write' case


>>>>> "Jan" == Jan Kratochvil <jan.kratochvil@redhat.com> writes:

Jan> In that Bug I made a comment
Jan> # evaluate_subexp_c->OP_STRING ignores expect_type, GDB then tries to convert
Jan> # the non-matching type using malloc.
Jan> which I advocate below.

Jan> I believe if GDB adjusts the short/long types shouldn't it adjust also
Jan> char/whar_t types?  That is now the user must know the type of string in
Jan> advance which wasn't the case for arrays before.

Ok, I understand now.

What do you think of this?  It uses the expected type to construct the
array's values when it makes sense.

This version adds a test case for this too.

Tom

2011-05-11  Tom Tromey  <tromey@redhat.com>

	* c-lang.c (evaluate_subexp_c): Use expect_type if it is not
	NULL.

2011-05-11  Tom Tromey  <tromey@redhat.com>

	* gdb.base/charset.exp (string_display): Add tests to assign to
	arrays.
	* gdb.base/charset.c (short_array, int_array, long_array): New.

diff --git a/gdb/c-lang.c b/gdb/c-lang.c
index ad770bf..255fabe 100644
--- a/gdb/c-lang.c
+++ b/gdb/c-lang.c
@@ -978,6 +978,7 @@ evaluate_subexp_c (struct type *expect_type, struct expression *exp,
 	struct value *result;
 	enum c_string_type dest_type;
 	const char *dest_charset;
+	int satisfy_expected = 0;
 
 	obstack_init (&output);
 	cleanup = make_cleanup_obstack_free (&output);
@@ -1014,6 +1015,22 @@ evaluate_subexp_c (struct type *expect_type, struct expression *exp,
 	/* Ensure TYPE_LENGTH is valid for TYPE.  */
 	check_typedef (type);
 
+	/* If the caller expects an array of some integral type,
+	   satisfy them.  If something odder is expected, rely on the
+	   caller to cast.  */
+	if (expect_type && TYPE_CODE (expect_type) == TYPE_CODE_ARRAY)
+	  {
+	    struct type *element_type
+	      = check_typedef (TYPE_TARGET_TYPE (expect_type));
+
+	    if (TYPE_CODE (element_type) == TYPE_CODE_INT
+		|| TYPE_CODE (element_type) == TYPE_CODE_CHAR)
+	      {
+		type = element_type;
+		satisfy_expected = 1;
+	      }
+	  }
+
 	dest_charset = charset_for_string_type (dest_type, exp->gdbarch);
 
 	++*pos;
@@ -1036,7 +1053,9 @@ evaluate_subexp_c (struct type *expect_type, struct expression *exp,
 	if (noside == EVAL_SKIP)
 	  {
 	    /* Return a dummy value of the appropriate type.  */
-	    if ((dest_type & C_CHAR) != 0)
+	    if (expect_type != NULL)
+	      result = allocate_value (expect_type);
+	    else if ((dest_type & C_CHAR) != 0)
 	      result = allocate_value (type);
 	    else
 	      result = value_cstring ("", 0, type);
@@ -1061,9 +1080,30 @@ evaluate_subexp_c (struct type *expect_type, struct expression *exp,
 	    /* Write the terminating character.  */
 	    for (i = 0; i < TYPE_LENGTH (type); ++i)
 	      obstack_1grow (&output, 0);
-	    result = value_cstring (obstack_base (&output),
-				    obstack_object_size (&output),
-				    type);
+
+	    if (satisfy_expected)
+	      {
+		LONGEST low_bound, high_bound;
+		int element_size = TYPE_LENGTH (type);
+
+		if (get_discrete_bounds (TYPE_INDEX_TYPE (expect_type),
+					 &low_bound, &high_bound) < 0)
+		  {
+		    low_bound = 0;
+		    high_bound = (TYPE_LENGTH (expect_type) / element_size) - 1;
+		  }
+		if (obstack_object_size (&output) / element_size
+		    > (high_bound - low_bound + 1))
+		  error (_("Too many array elements"));
+
+		result = allocate_value (expect_type);
+		memcpy (value_contents_raw (result), obstack_base (&output),
+			obstack_object_size (&output));
+	      }
+	    else
+	      result = value_cstring (obstack_base (&output),
+				      obstack_object_size (&output),
+				      type);
 	  }
 	do_cleanups (cleanup);
 	return result;
diff --git a/gdb/testsuite/gdb.base/charset.c b/gdb/testsuite/gdb.base/charset.c
index 644fe47..df56c45 100644
--- a/gdb/testsuite/gdb.base/charset.c
+++ b/gdb/testsuite/gdb.base/charset.c
@@ -73,6 +73,11 @@ char32_t *String32;
 typedef wchar_t my_wchar_t;
 my_wchar_t myvar;
 
+/* Some arrays for simple assignment tests.  */
+short short_array[3];
+int int_array[3];
+long long_array[3];
+
 void
 init_string (char string[],
              char x,
diff --git a/gdb/testsuite/gdb.base/charset.exp b/gdb/testsuite/gdb.base/charset.exp
index 4e4cf09..b558bb2 100644
--- a/gdb/testsuite/gdb.base/charset.exp
+++ b/gdb/testsuite/gdb.base/charset.exp
@@ -617,4 +617,13 @@ if {$wchar_size == 4} {
 }
 
 
+foreach name {short int long} {
+    # We're really just checking to make sure this doesn't give an
+    # error.
+    gdb_test "print ${name}_array = \"hi\"" \
+	" = {.*}" \
+	"assign string to $name array"
+}
+
+
 gdb_exit 


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]