From patchwork Fri Mar 21 18:25:12 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Keith Seitz X-Patchwork-Id: 214 Return-Path: X-Original-To: siddhesh@wilcox.dreamhost.com Delivered-To: siddhesh@wilcox.dreamhost.com Received: from homiemail-mx22.g.dreamhost.com (caibbdcaabij.dreamhost.com [208.113.200.189]) by wilcox.dreamhost.com (Postfix) with ESMTP id 2164D36016D for ; Fri, 21 Mar 2014 11:25:24 -0700 (PDT) Received: by homiemail-mx22.g.dreamhost.com (Postfix, from userid 14314964) id B410E503A606; Fri, 21 Mar 2014 11:25:23 -0700 (PDT) X-Original-To: gdb@patchwork.siddhesh.in Delivered-To: x14314964@homiemail-mx22.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-mx22.g.dreamhost.com (Postfix) with ESMTPS id 8FCE6503A615 for ; Fri, 21 Mar 2014 11:25:23 -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 :content-type; q=dns; s=default; b=OLjHruDcqjbWbGQwhkRieopQXAhNR ErP9WTNWKMzPSsj+15k5cIYgQg07SThOE+EnIn2pxjknft+QvAE2WFf8XsaT6cEI UCOq3qmmkKgR640QgLfQLBZ1zxzOWc3Fd40nug7wp0O4LAJk3XZGSH8xMU75Iwqo rhz2eOr4Zpte7M= 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 :content-type; s=default; bh=cL76bb6VjQn4m65VgyJfHy5ykrI=; b=iZ9 Ub+eYcS4PscjobqyHG4FnBgzCFJRWYPOG56kSVUTiRdnF8fW75jKAEn/7yzRceEi WA9wYT7D3zVj9V3uGkDPJQXGTwnuNebH2LZBA27EUDBEry4qPI7bIQ5evsRArtOj que8ClyzxrKKG/0j4UPCGTiGYkP71QJcN6VYQPA0= Received: (qmail 31309 invoked by alias); 21 Mar 2014 18:25:22 -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 31299 invoked by uid 89); 21 Mar 2014 18:25:21 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-0.9 required=5.0 tests=AWL, BAYES_00, KAM_STOCKGEN, SPF_HELO_PASS, SPF_PASS, T_RP_MATCHES_RCVD 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, 21 Mar 2014 18:25:14 +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 s2LIPDkf003588 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Fri, 21 Mar 2014 14:25:13 -0400 Received: from valrhona.uglyboxes.com (ovpn01.gateway.prod.ext.phx2.redhat.com [10.5.9.1]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s2LIPCge026373 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES128-SHA bits=128 verify=NO) for ; Fri, 21 Mar 2014 14:25:13 -0400 Message-ID: <532C8408.9030905@redhat.com> Date: Fri, 21 Mar 2014 11:25:12 -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: [RFA] c++/16675 (incorrect sizeof reference types) X-IsSubscribed: yes X-DH-Original-To: gdb@patchwork.siddhesh.in Hi, This bug is easily demonstrated (from the bugzilla): typedef unsigned char a4[4]; a4 p1; a4& p2 = p1; std::cout< 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-03-20 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 11631ba..6cbc9f8 100644 --- a/gdb/c-exp.y +++ b/gdb/c-exp.y @@ -771,13 +771,22 @@ exp : SELECTOR '(' name ')' ; exp : SIZEOF '(' type ')' %prec UNARY - { write_exp_elt_opcode (OP_LONG); + { struct type *type = $3; + write_exp_elt_opcode (OP_LONG); write_exp_elt_type (lookup_signed_typename (parse_language, parse_gdbarch, "int")); - CHECK_TYPEDEF ($3); - write_exp_elt_longcst ((LONGEST) TYPE_LENGTH ($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 ((LONGEST) TYPE_LENGTH (type)); write_exp_elt_opcode (OP_LONG); } + ; exp : REINTERPRET_CAST '<' type_exp '>' '(' exp ')' %prec UNARY diff --git a/gdb/eval.c b/gdb/eval.c index 36615e1..c1e47e0 100644 --- a/gdb/eval.c +++ b/gdb/eval.c @@ -3025,31 +3025,39 @@ 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)); - return value_from_longest (size_type, (LONGEST) TYPE_LENGTH (type)); + 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: (*pos) += 4; - type = check_typedef (SYMBOL_TYPE (exp->elts[pc + 2].symbol)); - return - value_from_longest (size_type, (LONGEST) TYPE_LENGTH (type)); + type = SYMBOL_TYPE (exp->elts[pc + 2].symbol); + break; 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" +}