From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 16915 invoked by alias); 23 Nov 2010 01:11:56 -0000 Received: (qmail 16901 invoked by uid 22791); 23 Nov 2010 01:11:55 -0000 X-SWARE-Spam-Status: No, hits=-2.1 required=5.0 tests=AWL,BAYES_00,T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from rock.gnat.com (HELO rock.gnat.com) (205.232.38.15) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Tue, 23 Nov 2010 01:11:49 +0000 Received: from localhost (localhost.localdomain [127.0.0.1]) by filtered-rock.gnat.com (Postfix) with ESMTP id 148042BABA5; Mon, 22 Nov 2010 20:11:48 -0500 (EST) Received: from rock.gnat.com ([127.0.0.1]) by localhost (rock.gnat.com [127.0.0.1]) (amavisd-new, port 10024) with LMTP id cAF7TgECgwcp; Mon, 22 Nov 2010 20:11:48 -0500 (EST) Received: from joel.gnat.com (localhost.localdomain [127.0.0.1]) by rock.gnat.com (Postfix) with ESMTP id D29B12BABA4; Mon, 22 Nov 2010 20:11:47 -0500 (EST) Received: by joel.gnat.com (Postfix, from userid 1000) id B5EEE1457E1; Mon, 22 Nov 2010 17:11:44 -0800 (PST) From: Joel Brobecker To: gdb-patches@sourceware.org Cc: Joel Brobecker Subject: [commit/Ada] array pointers encoded as typedef to fat pointer Date: Tue, 23 Nov 2010 01:11:00 -0000 Message-Id: <1290474703-1767-1-git-send-email-brobecker@adacore.com> 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: 2010-11/txt/msg00334.txt.bz2 A recent change in check_typedef caused the following regression, considering: type String_Access is access String; S1 : String_Access := null; Trying to print S1, we get: (gdb) print s1 $1 = (string) (null) The type name is wrong. We were expecting: (gdb) print s1 $1 = (string_bug.string_access) (null) The extensive comment in this patch explains how pointers to arrays are encoded when the array is a "fat pointer". What happened is that the change in check_typedef broke a type-equality test that we were performing. The test really was on the fringe, but it turns out that, for what we're doing, we're really only interested in the main-type portion of the type. The patch adjust the check accordingly. gdb/ChangeLog: * ada-lang.c (ada_to_fixed_type): Expand function documentation. Return the original type if the main type portions match rather than when the type themselves match. Tested on x86_64-linux. Checked in. --- gdb/ChangeLog | 6 ++++++ gdb/ada-lang.c | 38 ++++++++++++++++++++++++++++++++++++-- 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 8872ab4..dd91159 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,11 @@ 2010-11-22 Joel Brobecker + * ada-lang.c (ada_to_fixed_type): Expand function documentation. + Return the original type if the main type portions match rather + than when the type themselves match. + +2010-11-22 Joel Brobecker + * ada-lang.c (ada_template_to_fixed_record_type_1): For dynamic fields, check the field size against the maximum object size. diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c index 341db4a..4471481 100644 --- a/gdb/ada-lang.c +++ b/gdb/ada-lang.c @@ -7659,7 +7659,23 @@ ada_to_fixed_type_1 (struct type *type, const gdb_byte *valaddr, /* The same as ada_to_fixed_type_1, except that it preserves the type if it is a TYPE_CODE_TYPEDEF of a type that is already fixed. - ada_to_fixed_type_1 would return the type referenced by TYPE. */ + + The typedef layer needs be preserved in order to differentiate between + arrays and array pointers when both types are implemented using the same + fat pointer. In the array pointer case, the pointer is encoded as + a typedef of the pointer type. For instance, considering: + + type String_Access is access String; + S1 : String_Access := null; + + To the debugger, S1 is defined as a typedef of type String. But + to the user, it is a pointer. So if the user tries to print S1, + we should not dereference the array, but print the array address + instead. + + If we didn't preserve the typedef layer, we would lose the fact that + the type is to be presented as a pointer (needs de-reference before + being printed). And we would also use the source-level type name. */ struct type * ada_to_fixed_type (struct type *type, const gdb_byte *valaddr, @@ -7669,8 +7685,26 @@ ada_to_fixed_type (struct type *type, const gdb_byte *valaddr, struct type *fixed_type = ada_to_fixed_type_1 (type, valaddr, address, dval, check_tag); + /* If TYPE is a typedef and its target type is the same as the FIXED_TYPE, + then preserve the typedef layer. + + Implementation note: We can only check the main-type portion of + the TYPE and FIXED_TYPE, because eliminating the typedef layer + from TYPE now returns a type that has the same instance flags + as TYPE. For instance, if TYPE is a "typedef const", and its + target type is a "struct", then the typedef elimination will return + a "const" version of the target type. See check_typedef for more + details about how the typedef layer elimination is done. + + brobecker/2010-11-19: It seems to me that the only case where it is + useful to preserve the typedef layer is when dealing with fat pointers. + Perhaps, we could add a check for that and preserve the typedef layer + only in that situation. But this seems unecessary so far, probably + because we call check_typedef/ada_check_typedef pretty much everywhere. + */ if (TYPE_CODE (type) == TYPE_CODE_TYPEDEF - && TYPE_TARGET_TYPE (type) == fixed_type) + && (TYPE_MAIN_TYPE (TYPE_TARGET_TYPE (type)) + == TYPE_MAIN_TYPE (fixed_type))) return type; return fixed_type; -- 1.7.1