From patchwork Fri Apr 11 21:22:33 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Keith Seitz X-Patchwork-Id: 516 X-Patchwork-Delegate: tromey@sourceware.org Return-Path: X-Original-To: siddhesh@wilcox.dreamhost.com Delivered-To: siddhesh@wilcox.dreamhost.com Received: from homiemail-mx20.g.dreamhost.com (mx2.sub5.homie.mail.dreamhost.com [208.113.200.128]) by wilcox.dreamhost.com (Postfix) with ESMTP id 561BD36007C for ; Fri, 11 Apr 2014 14:22:41 -0700 (PDT) Received: by homiemail-mx20.g.dreamhost.com (Postfix, from userid 14314964) id 17DA340FB6AA1; Fri, 11 Apr 2014 14:22:41 -0700 (PDT) X-Original-To: gdb@patchwork.siddhesh.in Delivered-To: x14314964@homiemail-mx20.g.dreamhost.com Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by homiemail-mx20.g.dreamhost.com (Postfix) with ESMTPS id E0E17410D5D81 for ; Fri, 11 Apr 2014 14:22:40 -0700 (PDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:message-id:date:from:mime-version:to:subject :references:in-reply-to:content-type; q=dns; s=default; b=VgGS2d Er37rz4TObMsNfdwzmrWc3vHNmNxtNCQNQXrK6D0yh4uv0ykIzs//IlNGE91C4Y8 cIzJjSQaNnoD4Nw3E/n/MVUXCPW/3W0jt31okKuL5HSt1oxo9Hup3hgui3vgeBTK +sj/CvyH4glG2Dl5FnbuTaVIHUdx5Lf41gIkw= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:message-id:date:from:mime-version:to:subject :references:in-reply-to:content-type; s=default; bh=7Bv6tCoi3KBg gsRXIRg2wvt6gx0=; b=kuPkpQCngspYGDbFy0t4J8/IMDswFlvV3RpFWxXZv9UQ J68j0IgQHAUVsyWuKug75w9Ar0gvGqsyIK3SU7gjm/hqiK908vqc1daA5OgWXUxx 0MPiJgJnNX0hbv6kaWBE2MN07rMAYfsFyBIzNmetid/qfM2oISvAq+ac8ULkJnw= Received: (qmail 9962 invoked by alias); 11 Apr 2014 21:22:39 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 9951 invoked by uid 89); 11 Apr 2014 21:22:38 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.2 required=5.0 tests=AWL, BAYES_00, KAM_STOCKGEN, RP_MATCHES_RCVD, SPF_HELO_PASS, SPF_PASS autolearn=no version=3.3.2 X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 11 Apr 2014 21:22:37 +0000 Received: from int-mx01.intmail.prod.int.phx2.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s3BLMYlw004530 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Fri, 11 Apr 2014 17:22:35 -0400 Received: from valrhona.uglyboxes.com (ovpn01.gateway.prod.ext.phx2.redhat.com [10.5.9.1]) by int-mx01.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id s3BLMXiU005063 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES128-SHA bits=128 verify=NO) for ; Fri, 11 Apr 2014 17:22:34 -0400 Message-ID: <53485D19.4030203@redhat.com> Date: Fri, 11 Apr 2014 14:22:33 -0700 From: Keith Seitz User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Thunderbird/24.3.0 MIME-Version: 1.0 To: "gp >> \"gdb-patches@sourceware.org ml\"" Subject: Re: [RFA] c++/16675 (incorrect sizeof reference types) References: <532C8408.9030905@redhat.com> <87y4zdp123.fsf@fleche.redhat.com> In-Reply-To: <87y4zdp123.fsf@fleche.redhat.com> X-IsSubscribed: yes X-DH-Original-To: gdb@patchwork.siddhesh.in On 04/10/2014 10:05 AM, Tom Tromey wrote: >>>>>> "Keith" == Keith Seitz writes: > > Keith> 2014-03-20 Keith Seitz > > Keith> PR c++/16675 > Keith> * c-exp.y (exp : SIZEOF '(' type ')'): Handle reference types. > Keith> * eval.c (evaluate_subexp_for_sizeof): Refactor and handle > Keith> reference types. > > Keith> testsuite/ChangeLog > Keith> 2014-03-20 Keith Seitz > > Keith> PR c++/16675 > Keith> * gdb.cp/cpsizeof.exp: New file. > Keith> * gdb.cp/cpsizeof.cc: New file. > > This is ok. Thanks. I've pushed this patch. A patch from yesterday conflicted in eval.c:evaluate_subexp_for_sizeof. I'm attaching the patch again for reference. Thank you for the review, Tom. Keith ChangeLog 2014-04-11 Keith Seitz PR c++/16675 * c-exp.y (exp : SIZEOF '(' type ')'): Handle reference types. * eval.c (evaluate_subexp_for_sizeof): Refactor and handle reference types. testsuite/ChangeLog 2014-04-11 Keith Seitz PR c++/16675 * gdb.cp/cpsizeof.exp: New file. * gdb.cp/cpsizeof.cc: New file. diff --git a/gdb/c-exp.y b/gdb/c-exp.y index fc79807..f39391c 100644 --- a/gdb/c-exp.y +++ b/gdb/c-exp.y @@ -787,14 +787,22 @@ exp : SELECTOR '(' name ')' ; exp : SIZEOF '(' type ')' %prec UNARY - { write_exp_elt_opcode (pstate, OP_LONG); + { struct type *type = $3; + write_exp_elt_opcode (pstate, OP_LONG); write_exp_elt_type (pstate, lookup_signed_typename (parse_language (pstate), parse_gdbarch (pstate), "int")); - CHECK_TYPEDEF ($3); + CHECK_TYPEDEF (type); + + /* $5.3.3/2 of the C++ Standard (n3290 draft) + says of sizeof: "When applied to a reference + or a reference type, the result is the size of + the referenced type." */ + if (TYPE_CODE (type) == TYPE_CODE_REF) + type = check_typedef (TYPE_TARGET_TYPE (type)); write_exp_elt_longcst (pstate, - (LONGEST) TYPE_LENGTH ($3)); + (LONGEST) TYPE_LENGTH (type)); write_exp_elt_opcode (pstate, OP_LONG); } ; diff --git a/gdb/eval.c b/gdb/eval.c index d29960a..c6ddd31 100644 --- a/gdb/eval.c +++ b/gdb/eval.c @@ -3030,21 +3030,22 @@ evaluate_subexp_for_sizeof (struct expression *exp, int *pos, && TYPE_CODE (type) != TYPE_CODE_REF && TYPE_CODE (type) != TYPE_CODE_ARRAY) error (_("Attempt to take contents of a non-pointer value.")); - type = check_typedef (TYPE_TARGET_TYPE (type)); if (is_dynamic_type (type)) type = value_type (value_ind (val)); - return value_from_longest (size_type, (LONGEST) TYPE_LENGTH (type)); + else + type = TYPE_TARGET_TYPE (type); + break; case UNOP_MEMVAL: (*pos) += 3; - type = check_typedef (exp->elts[pc + 1].type); - return value_from_longest (size_type, (LONGEST) TYPE_LENGTH (type)); + type = exp->elts[pc + 1].type; + break; case UNOP_MEMVAL_TYPE: (*pos) += 1; val = evaluate_subexp (NULL, exp, pos, EVAL_AVOID_SIDE_EFFECTS); - type = check_typedef (value_type (val)); - return value_from_longest (size_type, (LONGEST) TYPE_LENGTH (type)); + type = value_type (val); + break; case OP_VAR_VALUE: type = check_typedef (SYMBOL_TYPE (exp->elts[pc + 2].symbol)); @@ -3055,8 +3056,7 @@ evaluate_subexp_for_sizeof (struct expression *exp, int *pos, } else (*pos) += 4; - return - value_from_longest (size_type, (LONGEST) TYPE_LENGTH (type)); + break; /* Deal with the special case if NOSIDE is EVAL_NORMAL and the resulting type of the subscript is a variable length array type. In this case we @@ -3080,8 +3080,8 @@ evaluate_subexp_for_sizeof (struct expression *exp, int *pos, if (TYPE_RANGE_DATA (type)->flag_bound_evaluated) { val = evaluate_subexp (NULL_TYPE, exp, pos, EVAL_NORMAL); - return value_from_longest - (size_type, (LONGEST) TYPE_LENGTH (value_type (val))); + type = value_type (val); + break; } } } @@ -3091,9 +3091,18 @@ evaluate_subexp_for_sizeof (struct expression *exp, int *pos, default: val = evaluate_subexp (NULL_TYPE, exp, pos, EVAL_AVOID_SIDE_EFFECTS); - return value_from_longest (size_type, - (LONGEST) TYPE_LENGTH (value_type (val))); + type = value_type (val); + break; } + + /* $5.3.3/2 of the C++ Standard (n3290 draft) says of sizeof: + "When applied to a reference or a reference type, the result is + the size of the referenced type." */ + CHECK_TYPEDEF (type); + if (exp->language_defn->la_language == language_cplus + && TYPE_CODE (type) == TYPE_CODE_REF) + type = check_typedef (TYPE_TARGET_TYPE (type)); + return value_from_longest (size_type, (LONGEST) TYPE_LENGTH (type)); } /* Parse a type expression in the string [P..P+LENGTH). */ diff --git a/gdb/testsuite/gdb.cp/cpsizeof.cc b/gdb/testsuite/gdb.cp/cpsizeof.cc new file mode 100644 index 0000000..0760cfc --- /dev/null +++ b/gdb/testsuite/gdb.cp/cpsizeof.cc @@ -0,0 +1,71 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2014 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +struct Class +{ + int a; + char b; + long c; + + Class () : a (1), b ('2'), c (3) { } +}; + +union Union +{ + Class *kp; + char a; + int b; + long c; +}; + +enum Enum { A, B, C, D }; + +typedef unsigned char a4[4]; +typedef unsigned char a8[8]; +typedef unsigned char a12[12]; +typedef Class c4[4]; +typedef Union u8[8]; +typedef Enum e12[12]; + +#define T(N) \ + N N ## obj; \ + N& N ## _ref = N ## obj; \ + N* N ## p = &(N ## obj); \ + N*& N ## p_ref = N ## p; \ + int size_ ## N = sizeof (N ## _ref); \ + int size_ ## N ## p = sizeof (N ## p_ref); \ + +int +main (void) +{ + T (char); + T (int); + T (long); + T (float); + T (double); + T (a4); + T (a8); + T (a12); + T (Class); + T (Union); + T (Enum); + T (c4); + T (u8); + T (e12); + + return 0; /* break here */ +} diff --git a/gdb/testsuite/gdb.cp/cpsizeof.exp b/gdb/testsuite/gdb.cp/cpsizeof.exp new file mode 100644 index 0000000..f55af9c --- /dev/null +++ b/gdb/testsuite/gdb.cp/cpsizeof.exp @@ -0,0 +1,40 @@ +# sizeof() tests [c++/16675] +# Copyright 2014 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +standard_testfile .cc + +if {[skip_cplus_tests]} { continue } + +if {[prepare_for_testing ${testfile}.exp $testfile $srcfile {debug c++}] } { + return -1 +} + +if {![runto_main]} { + perror "could not run to main" + continue +} + +gdb_breakpoint [gdb_get_line_number "break here"] +gdb_continue_to_breakpoint "break here" + +# Compare sizeof from the compiler and gdb. Do this once with the actual +# type name and once with a reference variable. +foreach v {char int long float double a4 a8 a12 Class Union Enum c4 u8 e12} { + gdb_test "print size_$v == sizeof (${v}&)" "= true" + gdb_test "print size_$v == sizeof (${v}_ref)" "= true" + gdb_test "print size_${v}p == sizeof (${v}*&)" "= true" + gdb_test "print size_${v}p == sizeof (${v}p_ref)" "= true" +}