From: Tom Tromey <tromey@redhat.com>
To: Jan Kratochvil <jan.kratochvil@redhat.com>
Cc: Yao Qi <yao@codesourcery.com>, gdb-patches@sourceware.org
Subject: Re: RFC: fix `gdb -write' case
Date: Wed, 11 May 2011 19:42:00 -0000 [thread overview]
Message-ID: <m3r585nhxg.fsf@fleche.redhat.com> (raw)
In-Reply-To: <20110511143828.GA28962@host1.jankratochvil.net> (Jan Kratochvil's message of "Wed, 11 May 2011 16:38:28 +0200")
>>>>> "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
next prev parent reply other threads:[~2011-05-11 19:42 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-05-06 17:12 Tom Tromey
2011-05-09 3:11 ` Yao Qi
2011-05-09 14:54 ` Tom Tromey
2011-05-10 2:03 ` Yao Qi
2011-05-10 14:16 ` Tom Tromey
2011-05-11 8:06 ` Jan Kratochvil
2011-05-11 14:38 ` Jan Kratochvil
2011-05-11 19:42 ` Tom Tromey [this message]
2011-05-22 18:24 ` Jan Kratochvil
2011-05-23 20:24 ` Tom Tromey
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=m3r585nhxg.fsf@fleche.redhat.com \
--to=tromey@redhat.com \
--cc=gdb-patches@sourceware.org \
--cc=jan.kratochvil@redhat.com \
--cc=yao@codesourcery.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox