From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 29630 invoked by alias); 11 May 2011 19:42:15 -0000 Received: (qmail 29619 invoked by uid 22791); 11 May 2011 19:42:14 -0000 X-SWARE-Spam-Status: No, hits=-6.8 required=5.0 tests=AWL,BAYES_00,RCVD_IN_DNSWL_HI,SPF_HELO_PASS,TW_CP,T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Wed, 11 May 2011 19:41:56 +0000 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id p4BJfoHv017348 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 11 May 2011 15:41:50 -0400 Received: from ns3.rdu.redhat.com (ns3.rdu.redhat.com [10.11.255.199]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id p4BJfoq8000466; Wed, 11 May 2011 15:41:50 -0400 Received: from opsy.redhat.com (ovpn01.gateway.prod.ext.phx2.redhat.com [10.5.9.1]) by ns3.rdu.redhat.com (8.13.8/8.13.8) with ESMTP id p4BJfnri000659; Wed, 11 May 2011 15:41:49 -0400 Received: by opsy.redhat.com (Postfix, from userid 500) id D67D8378498; Wed, 11 May 2011 13:41:48 -0600 (MDT) From: Tom Tromey To: Jan Kratochvil Cc: Yao Qi , gdb-patches@sourceware.org Subject: Re: RFC: fix `gdb -write' case References: <4DC75B31.2020501@codesourcery.com> <20110511143828.GA28962@host1.jankratochvil.net> Date: Wed, 11 May 2011 19:42:00 -0000 In-Reply-To: <20110511143828.GA28962@host1.jankratochvil.net> (Jan Kratochvil's message of "Wed, 11 May 2011 16:38:28 +0200") Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.2 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2011-05/txt/msg00294.txt.bz2 >>>>> "Jan" == Jan Kratochvil 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 * c-lang.c (evaluate_subexp_c): Use expect_type if it is not NULL. 2011-05-11 Tom Tromey * 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