From patchwork Thu Sep 12 09:24:21 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexandre Oliva X-Patchwork-Id: 1161467 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-508945-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=adacore.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="OlK4+KdY"; dkim-atps=neutral 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 ozlabs.org (Postfix) with ESMTPS id 46TYJW077dz9s7T for ; Thu, 12 Sep 2019 19:24:57 +1000 (AEST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:cc:subject:date:message-id:mime-version:content-type :content-transfer-encoding; q=dns; s=default; b=CjG38tRW2AcpAGqO CmR0U4oQ09y2lshGuMRplA/ipqseEaQehkoMYmDLarStL4CYaEAQnFosCBVge+Yt rvzkkxHyhbnHL3Jr8M0ZnBxuheRhwpAfWTktGl7J2lNCnOKxcFUQVqcrhWqJN73l yiqThKSy6HEdgF5ghN2AXmr1jGg= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:cc:subject:date:message-id:mime-version:content-type :content-transfer-encoding; s=default; bh=T8xJSOq8hapJ12E5irJhdf Cq6XM=; b=OlK4+KdY5FaJPJm2eFVxBwxKjoCjnLxdKk2Y8i9XgBNYxWoQBjtVYa fNGKSQpkKhteT//DcFh3+tX5S8aEMER9Xjyp8omHR5gvMpvkBcWwjP+xpYL6txI6 Z3Y3yHGRsPQr+cpBucJ/zZJpapyvb59+fFAEJfhoLHye1e/OEOFvk= Received: (qmail 49912 invoked by alias); 12 Sep 2019 09:24:49 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 49848 invoked by uid 89); 12 Sep 2019 09:24:44 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-26.9 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.1 spammy=Alexandre, alexandre, oliva, regstrapped X-HELO: rock.gnat.com Received: from rock.gnat.com (HELO rock.gnat.com) (205.232.38.15) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 12 Sep 2019 09:24:42 +0000 Received: from localhost (localhost.localdomain [127.0.0.1]) by filtered-rock.gnat.com (Postfix) with ESMTP id 5A416117811; Thu, 12 Sep 2019 05:24:40 -0400 (EDT) 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 wg7pqU1sIQ60; Thu, 12 Sep 2019 05:24:40 -0400 (EDT) Received: from free.home (tron.gnat.com [IPv6:2620:20:4000:0:46a8:42ff:fe0e:e294]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by rock.gnat.com (Postfix) with ESMTPS id D607B11780C; Thu, 12 Sep 2019 05:24:39 -0400 (EDT) Received: from livre (livre.home [172.31.160.2]) by free.home (8.15.2/8.15.2) with ESMTPS id x8C9OLg6618018 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Thu, 12 Sep 2019 06:24:21 -0300 From: Alexandre Oliva To: gcc-patches@gcc.gnu.org Cc: jason@redhat.com, ccoutant@gmail.com Subject: [PATCH] DWARF array bounds missing from C++ array definitions Date: Thu, 12 Sep 2019 06:24:21 -0300 Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.2 (gnu/linux) MIME-Version: 1.0 A variable redeclaration or definition that provides additional type information for it, e.g. outermost array bounds, is not reflected in the debug information for the variable. With this patch, the debug info of the variable specialization gets a type attribute with the adjusted type. This patch affects mostly only array bounds. However, when the symbolic type used in a declaration and in a definition are different, although they refer to the same type, debug information will end up (correctly?) naming different symbolic types in the specification and the definition. Also, when a readonly declaration of an array loses the readonly flag at the definition because of the initializer, the definition may end up referencing a type while the specification refers to a const-qualified version of that type. If the type of the variable is already const-qualified, e.g. an array of a const type, the difference is meaningless. Regstrapped on x86_64-linux-gnu. Ok to install? for gcc/ChangeLog * dwarf2out.c (completing_type_p): New. (gen_variable_die): Use it. for gcc/testsuite/ChangeLog * gcc.dg/debug/dwarf2/array-0.c: New. * gcc.dg/debug/dwarf2/array-1.c: New. * gcc.dg/debug/dwarf2/array-2.c: New. * gcc.dg/debug/dwarf2/array-3.c: New. * g++.dg/debug/dwarf2/array-0.C: New. * g++.dg/debug/dwarf2/array-1.C: New. * g++.dg/debug/dwarf2/array-2.C: New. Based on libstdc++-v3's src/c++98/pool_allocator.cc:__pool_alloc_base::_S_heap_size. * g++.dg/debug/dwarf2/array-3.C: New. Based on gcc's config/i386/i386-features.c:xlogue_layout::s_instances. * g++.dg/debug/dwarf2/array-4.C: New. --- gcc/dwarf2out.c | 31 ++++++++++++++++++++++++++- gcc/testsuite/g++.dg/debug/dwarf2/array-0.C | 13 +++++++++++ gcc/testsuite/g++.dg/debug/dwarf2/array-1.C | 13 +++++++++++ gcc/testsuite/g++.dg/debug/dwarf2/array-2.C | 15 +++++++++++++ gcc/testsuite/g++.dg/debug/dwarf2/array-3.C | 20 +++++++++++++++++ gcc/testsuite/g++.dg/debug/dwarf2/array-4.C | 16 ++++++++++++++ gcc/testsuite/gcc.dg/debug/dwarf2/array-0.c | 10 +++++++++ gcc/testsuite/gcc.dg/debug/dwarf2/array-1.c | 10 +++++++++ gcc/testsuite/gcc.dg/debug/dwarf2/array-2.c | 8 +++++++ gcc/testsuite/gcc.dg/debug/dwarf2/array-3.c | 8 +++++++ 10 files changed, 143 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/g++.dg/debug/dwarf2/array-0.C create mode 100644 gcc/testsuite/g++.dg/debug/dwarf2/array-1.C create mode 100644 gcc/testsuite/g++.dg/debug/dwarf2/array-2.C create mode 100644 gcc/testsuite/g++.dg/debug/dwarf2/array-3.C create mode 100644 gcc/testsuite/g++.dg/debug/dwarf2/array-4.C create mode 100644 gcc/testsuite/gcc.dg/debug/dwarf2/array-0.c create mode 100644 gcc/testsuite/gcc.dg/debug/dwarf2/array-1.c create mode 100644 gcc/testsuite/gcc.dg/debug/dwarf2/array-2.c create mode 100644 gcc/testsuite/gcc.dg/debug/dwarf2/array-3.c diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index c359c2d4af981..ad533c14d2480 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -23687,6 +23687,33 @@ local_function_static (tree decl) && TREE_CODE (DECL_CONTEXT (decl)) == FUNCTION_DECL; } +/* Return true iff DECL completes (overrides) the type of OLD_DIE + within CONTEXT_DIE. */ + +static bool +completing_type_p (tree decl, dw_die_ref old_die, dw_die_ref context_die) +{ + tree type = TREE_TYPE (decl); + int cv_quals; + + if (decl_by_reference_p (decl)) + { + type = TREE_TYPE (type); + cv_quals = TYPE_UNQUALIFIED; + } + else + cv_quals = decl_quals (decl); + + dw_die_ref type_die = modified_type_die (type, + cv_quals | TYPE_QUALS (type), + false, + context_die); + + dw_die_ref old_type_die = get_AT_ref (old_die, DW_AT_type); + + return type_die != old_type_die; +} + /* Generate a DIE to represent a declared data object. Either DECL or ORIGIN must be non-null. */ @@ -23939,7 +23966,9 @@ gen_variable_die (tree decl, tree origin, dw_die_ref context_die) && !DECL_ABSTRACT_P (decl_or_origin) && variably_modified_type_p (TREE_TYPE (decl_or_origin), decl_function_context - (decl_or_origin)))) + (decl_or_origin))) + || (old_die && specialization_p + && completing_type_p (decl_or_origin, old_die, context_die))) { tree type = TREE_TYPE (decl_or_origin); diff --git a/gcc/testsuite/g++.dg/debug/dwarf2/array-0.C b/gcc/testsuite/g++.dg/debug/dwarf2/array-0.C new file mode 100644 index 0000000000000..a3458bd0d32a4 --- /dev/null +++ b/gcc/testsuite/g++.dg/debug/dwarf2/array-0.C @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-options "-gdwarf-2 -dA" } */ +struct S +{ + static int array[42]; +}; + +int S::array[42]; + +/* Verify that we get only one DW_TAG_subrange_type with a + DW_AT_upper_bound. */ +/* { dg-final { scan-assembler-times " DW_TAG_subrange_type" 2 } } */ +/* { dg-final { scan-assembler-times " DW_AT_upper_bound" 1 } } */ diff --git a/gcc/testsuite/g++.dg/debug/dwarf2/array-1.C b/gcc/testsuite/g++.dg/debug/dwarf2/array-1.C new file mode 100644 index 0000000000000..e8fd6f8ffea56 --- /dev/null +++ b/gcc/testsuite/g++.dg/debug/dwarf2/array-1.C @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-options "-gdwarf-2 -dA" } */ +struct S +{ + static int array[]; +}; + +int S::array[42]; + +/* Verify that we get two DW_TAG_subrange_type, only one of which with + a DW_AT_upper_bound. */ +/* { dg-final { scan-assembler-times " DW_TAG_subrange_type" 4 } } */ +/* { dg-final { scan-assembler-times " DW_AT_upper_bound" 1 } } */ diff --git a/gcc/testsuite/g++.dg/debug/dwarf2/array-2.C b/gcc/testsuite/g++.dg/debug/dwarf2/array-2.C new file mode 100644 index 0000000000000..dd17812043898 --- /dev/null +++ b/gcc/testsuite/g++.dg/debug/dwarf2/array-2.C @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-options "-gdwarf-2 -dA" } */ +struct S +{ + typedef int i_t; + static i_t array[42]; +}; + +int S::array[42]; + +/* Verify that we get two DW_TAG_subrange_type (plus abbrev), and two + DW_AT_upper_bound, because a different symbolic name is used for + the array element type. */ +/* { dg-final { scan-assembler-times " DW_TAG_subrange_type" 3 } } */ +/* { dg-final { scan-assembler-times " DW_AT_upper_bound" 2 } } */ diff --git a/gcc/testsuite/g++.dg/debug/dwarf2/array-3.C b/gcc/testsuite/g++.dg/debug/dwarf2/array-3.C new file mode 100644 index 0000000000000..8db6133b76585 --- /dev/null +++ b/gcc/testsuite/g++.dg/debug/dwarf2/array-3.C @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-options "-gdwarf-2 -dA" } */ +struct S +{ + S() {} + ~S() {} + static const S array[2]; +}; + +const S S::array[2] = { S(), S() }; + +/* Verify that we get only one DW_TAG_subrange_type (plus the abbrev), + and one DW_AT_upper_bound (non-abbrev), because the array + definition loses the readonly wrapper for the array type because of + the dynamic initializers. The const types are 4: S, S*, int, and + S[4], plus the abbrev. A const version of S[4] doesn't make sense, + but we output it. */ +/* { dg-final { scan-assembler-times " DW_TAG_const_type" 5 } } */ +/* { dg-final { scan-assembler-times " DW_TAG_subrange_type" 2 } } */ +/* { dg-final { scan-assembler-times " DW_AT_upper_bound" 1 } } */ diff --git a/gcc/testsuite/g++.dg/debug/dwarf2/array-4.C b/gcc/testsuite/g++.dg/debug/dwarf2/array-4.C new file mode 100644 index 0000000000000..6b3f546c1b583 --- /dev/null +++ b/gcc/testsuite/g++.dg/debug/dwarf2/array-4.C @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-options "-gdwarf-2 -dA" } */ +struct S +{ + S() {} + ~S() {} +}; + +const S array[2] = { S(), S() }; + +/* Like array-3, but with a non-member array without a separate + declaration, to check that we don't issue the nonsensical + DW_TAG_const_type used by the member array declaration there. */ +/* { dg-final { scan-assembler-times " DW_TAG_const_type" 4 } } */ +/* { dg-final { scan-assembler-times " DW_TAG_subrange_type" 2 } } */ +/* { dg-final { scan-assembler-times " DW_AT_upper_bound" 1 } } */ diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/array-0.c b/gcc/testsuite/gcc.dg/debug/dwarf2/array-0.c new file mode 100644 index 0000000000000..b06392e04a2db --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/dwarf2/array-0.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-options "-gdwarf-2 -dA" } */ +extern int array[42]; + +int array[42]; + +/* Verify that we get only one DW_TAG_subtrange_type (plus abbrev), + with a DW_AT_upper_bound. */ +/* { dg-final { scan-assembler-times " DW_TAG_subrange_type" 2 } } */ +/* { dg-final { scan-assembler-times " DW_AT_upper_bound" 1 } } */ diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/array-1.c b/gcc/testsuite/gcc.dg/debug/dwarf2/array-1.c new file mode 100644 index 0000000000000..ad8f466ef08ad --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/dwarf2/array-1.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-options "-gdwarf-2 -dA" } */ +extern int array[]; + +int array[42]; + +/* Verify that we get two DW_TAG_subtrange_type (each with an abbrev), + but only one DW_AT_upper_bound. */ +/* { dg-final { scan-assembler-times " DW_TAG_subrange_type" 4 } } */ +/* { dg-final { scan-assembler-times " DW_AT_upper_bound" 1 } } */ diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/array-2.c b/gcc/testsuite/gcc.dg/debug/dwarf2/array-2.c new file mode 100644 index 0000000000000..5d1606f0889fc --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/dwarf2/array-2.c @@ -0,0 +1,8 @@ +/* { dg-do compile } */ +/* { dg-options "-gdwarf-2 -dA" } */ +int array[42]; + +/* Verify that we get only one DW_TAG_subtrange_type (plus abbrev) + with DW_AT_upper_bound. */ +/* { dg-final { scan-assembler-times " DW_TAG_subrange_type" 2 } } */ +/* { dg-final { scan-assembler-times " DW_AT_upper_bound" 1 } } */ diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/array-3.c b/gcc/testsuite/gcc.dg/debug/dwarf2/array-3.c new file mode 100644 index 0000000000000..077a62ef9a3bf --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/dwarf2/array-3.c @@ -0,0 +1,8 @@ +/* { dg-do compile } */ +/* { dg-options "-gdwarf-2 -dA" } */ +int array[] = { 0, 1, 2 }; + +/* Verify that we get only one DW_TAG_subtrange_type (plus abbrev) + with DW_AT_upper_bound. */ +/* { dg-final { scan-assembler-times " DW_TAG_subrange_type" 2 } } */ +/* { dg-final { scan-assembler-times " DW_AT_upper_bound" 1 } } */