From patchwork Tue Aug 2 02:57:10 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexandre Oliva X-Patchwork-Id: 654484 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org 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 3s3LyK2hYWz9sXx for ; Tue, 2 Aug 2016 13:18:45 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=ygkjC1ii; dkim-atps=neutral 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; q=dns; s=default; b=tG+3d7vyEOslMhQFsd8vICAgwpVwjB4B3kOSuqvVtummWUviRw e3UdeXRyeOqPKEz0EGrWpBRv5+EyKv+nqRzG6u73a092zgs9Dnz9fltE5kouFNjg pM2pGnHZFoDVhoz/icgNUJ4w9kugQSE1ODKXqtJv8WiH17EGHnU9YEDFI= 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; s= default; bh=SDF2r4ZbxIpOrPwIMGIMyfNhiaY=; b=ygkjC1iiU9EbSwa+HXCA HonE71CzMXXxTRJIEzRmwu2Kl+CdcwGYb3tooh6e193434thUCEAA+uvw5TbxuBo kK0Gvv4wRr12w6iCuNw6Gqm3Y4KAShY2qzJMLtVndIQHOuOvY/cH+A0Sdb2/etwt bbWXBFAW/+uc0Z4AJWPYQ9E= Received: (qmail 58346 invoked by alias); 2 Aug 2016 03:18:15 -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 117780 invoked by uid 89); 2 Aug 2016 02:57:41 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-3.1 required=5.0 tests=BAYES_00, RP_MATCHES_RCVD, SPF_HELO_PASS autolearn=ham version=3.3.2 spammy=Lang, fresh, Tag, 3878 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 (AES256-GCM-SHA384 encrypted) ESMTPS; Tue, 02 Aug 2016 02:57:31 +0000 Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 2D8BF7AE8E; Tue, 2 Aug 2016 02:57:30 +0000 (UTC) Received: from freie.home (ovpn03.gateway.prod.ext.phx2.redhat.com [10.5.9.3]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id u722vRoN012842 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Mon, 1 Aug 2016 22:57:29 -0400 Received: from livre.home (livre.home [172.31.160.2]) by freie.home (8.15.2/8.15.2) with ESMTP id u722vAQA031996; Mon, 1 Aug 2016 23:57:10 -0300 From: Alexandre Oliva To: gcc-patches@gcc.gnu.org Cc: jason@redhat.com, ccoutant@gmail.com Subject: [PR63240] generate debug info for defaulted member functions Date: Mon, 01 Aug 2016 23:57:10 -0300 Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.5 (gnu/linux) MIME-Version: 1.0 This implements , a proposal already accepted for inclusion in DWARF-5, but using DW_AT_GNU_defaulted instead of DW_AT_defaulted as the attribute name, because the attribute id for DW_AT_defaulted is not yet publicly available. Regstrapped on x86_64-linux-gnu and i686-linux-gnu. Ok to install? for include/ChangeLog PR debug/63240 * dwarf2.def (DW_AT_GNU_defaulted): New. * dwarf2.h (enu dwarf_defaulted_attribute): New. for gcc/ChangeLog PR debug/63240 * langhooks-def.h (LANG_HOOKS_FUNCTION_DECL_DEFAULTED_INCLASS_P): Set default. (LANG_HOOKS_FUNCTION_DECL_DEFAULTED_OUTOFCLASS_P): Likewise. (LANG_HOOKS_DECLS): Add them. * langhooks.h (struct lang_hooks_for_decls): Add function_decl_defaulted_inclass_p and function_decl_defaulted_outofclass_p. * dwarf2out.c (gen_subprogram_die): Add DW_AT_GNU_defaulted attribute. for gcc/cp/ChangeLog PR debug/63240 * cp-objcp-common.c (cp_function_decl_defaulted_inclass_p, cp_function_decl_defaulted_outofclass_p): New. * cp-objcp-common.h (cp_function_decl_defaulted_inclass_p, cp_function_decl_defaulted_outofclass_p): Declare. (LANG_HOOKS_FUNCTION_DECL_DEFAULTED_INCLASS_P): Redefine. (LANG_HOOKS_FUNCTION_DECL_DEFAULTED_OUTOFCLASS_P): Redefine. for gcc/testsuite/ChangeLog PR debug/63240 * g++.dg/debug/dwarf2/defaulted-member-function-1.C: New. * g++.dg/debug/dwarf2/defaulted-member-function-2.C: New. * g++.dg/debug/dwarf2/defaulted-member-function-3.C: New. --- gcc/cp/cp-objcp-common.c | 22 ++++++++++++++++++ gcc/cp/cp-objcp-common.h | 8 +++++++ gcc/dwarf2out.c | 24 ++++++++++++++++++++ gcc/langhooks-def.h | 4 +++ gcc/langhooks.h | 8 +++++++ .../debug/dwarf2/defaulted-member-function-1.C | 14 ++++++++++++ .../debug/dwarf2/defaulted-member-function-2.C | 16 +++++++++++++ .../debug/dwarf2/defaulted-member-function-3.C | 13 +++++++++++ include/dwarf2.def | 2 ++ include/dwarf2.h | 8 +++++++ 10 files changed, 119 insertions(+) create mode 100644 gcc/testsuite/g++.dg/debug/dwarf2/defaulted-member-function-1.C create mode 100644 gcc/testsuite/g++.dg/debug/dwarf2/defaulted-member-function-2.C create mode 100644 gcc/testsuite/g++.dg/debug/dwarf2/defaulted-member-function-3.C diff --git a/gcc/cp/cp-objcp-common.c b/gcc/cp/cp-objcp-common.c index f7ddb00..daa1b7e 100644 --- a/gcc/cp/cp-objcp-common.c +++ b/gcc/cp/cp-objcp-common.c @@ -150,6 +150,28 @@ cp_function_decl_deleted_p (tree decl) && DECL_DELETED_FN (decl)); } +/* Return true if DECL is a special member function defaulted within + the class body. */ + +bool +cp_function_decl_defaulted_inclass_p (tree decl) +{ + return (decl + && DECL_LANG_SPECIFIC (STRIP_TEMPLATE (decl)) + && DECL_DEFAULTED_IN_CLASS_P (decl)); +} + +/* Return true if DECL is a special member function defaulted outside + the class body. */ + +bool +cp_function_decl_defaulted_outofclass_p (tree decl) +{ + return (decl + && DECL_LANG_SPECIFIC (STRIP_TEMPLATE (decl)) + && DECL_DEFAULTED_OUTSIDE_CLASS_P (decl)); +} + /* Stubs to keep c-opts.c happy. */ void push_file_scope (void) diff --git a/gcc/cp/cp-objcp-common.h b/gcc/cp/cp-objcp-common.h index 1bb19ee..7bba00d 100644 --- a/gcc/cp/cp-objcp-common.h +++ b/gcc/cp/cp-objcp-common.h @@ -28,6 +28,8 @@ extern tree objcp_tsubst_copy_and_build (tree, tree, tsubst_flags_t, extern bool cp_function_decl_explicit_p (tree decl); extern bool cp_function_decl_deleted_p (tree decl); +extern bool cp_function_decl_defaulted_inclass_p (tree decl); +extern bool cp_function_decl_defaulted_outofclass_p (tree decl); extern void cp_common_init_ts (void); /* Lang hooks that are shared between C++ and ObjC++ are defined here. Hooks @@ -134,6 +136,12 @@ extern void cp_common_init_ts (void); #define LANG_HOOKS_FUNCTION_DECL_EXPLICIT_P cp_function_decl_explicit_p #undef LANG_HOOKS_FUNCTION_DECL_DELETED_P #define LANG_HOOKS_FUNCTION_DECL_DELETED_P cp_function_decl_deleted_p +#undef LANG_HOOKS_FUNCTION_DECL_DEFAULTED_INCLASS_P +#define LANG_HOOKS_FUNCTION_DECL_DEFAULTED_INCLASS_P \ + cp_function_decl_defaulted_inclass_p +#undef LANG_HOOKS_FUNCTION_DECL_DEFAULTED_OUTOFCLASS_P +#define LANG_HOOKS_FUNCTION_DECL_DEFAULTED_OUTOFCLASS_P \ + cp_function_decl_defaulted_outofclass_p #undef LANG_HOOKS_OMP_PREDETERMINED_SHARING #define LANG_HOOKS_OMP_PREDETERMINED_SHARING cxx_omp_predetermined_sharing #undef LANG_HOOKS_OMP_CLAUSE_DEFAULT_CTOR diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index 8d6eeed..71fa5ad 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -20399,6 +20399,15 @@ gen_subprogram_die (tree decl, dw_die_ref context_die) add_type_attribute (subr_die, TREE_TYPE (TREE_TYPE (decl)), TYPE_UNQUALIFIED, false, context_die); } + + /* When we process the method declaration, we haven't seen the + out-of-class defaulted definition yet, so we have to recheck + now. */ + if (lang_hooks.decls.function_decl_defaulted_outofclass_p (decl) + && (! dwarf_strict) + && !get_AT (subr_die, DW_AT_GNU_defaulted)) + add_AT_unsigned (subr_die, DW_AT_GNU_defaulted, + DW_DEFAULTED_out_of_class); } } /* Create a fresh DIE for anything else. */ @@ -20450,6 +20459,21 @@ gen_subprogram_die (tree decl, dw_die_ref context_die) if (lang_hooks.decls.function_decl_deleted_p (decl) && (! dwarf_strict)) add_AT_flag (subr_die, DW_AT_GNU_deleted, 1); + + /* If this is a C++11 defaulted special function member then + generate a DW_AT_GNU_defaulted attribute. */ + if (lang_hooks.decls.function_decl_defaulted_inclass_p (decl) + && (! dwarf_strict)) + add_AT_unsigned (subr_die, DW_AT_GNU_defaulted, + DW_DEFAULTED_in_class); + /* It is likely that this will never hit, since we don't + have the out-of-class definition yet when we process the + class definition and the method declaration. We recheck + elsewhere, but leave it here just in case. */ + else if (lang_hooks.decls.function_decl_defaulted_outofclass_p (decl) + && (! dwarf_strict)) + add_AT_unsigned (subr_die, DW_AT_GNU_defaulted, + DW_DEFAULTED_out_of_class); } } /* Tag abstract instances with DW_AT_inline. */ diff --git a/gcc/langhooks-def.h b/gcc/langhooks-def.h index 034b3b7..23e1c74 100644 --- a/gcc/langhooks-def.h +++ b/gcc/langhooks-def.h @@ -210,6 +210,8 @@ extern tree lhd_make_node (enum tree_code); #define LANG_HOOKS_GETDECLS getdecls #define LANG_HOOKS_FUNCTION_DECL_EXPLICIT_P hook_bool_tree_false #define LANG_HOOKS_FUNCTION_DECL_DELETED_P hook_bool_tree_false +#define LANG_HOOKS_FUNCTION_DECL_DEFAULTED_INCLASS_P hook_bool_tree_false +#define LANG_HOOKS_FUNCTION_DECL_DEFAULTED_OUTOFCLASS_P hook_bool_tree_false #define LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL lhd_warn_unused_global_decl #define LANG_HOOKS_POST_COMPILATION_PARSING_CLEANUPS NULL #define LANG_HOOKS_DECL_OK_FOR_SIBCALL lhd_decl_ok_for_sibcall @@ -232,6 +234,8 @@ extern tree lhd_make_node (enum tree_code); LANG_HOOKS_GETDECLS, \ LANG_HOOKS_FUNCTION_DECL_EXPLICIT_P, \ LANG_HOOKS_FUNCTION_DECL_DELETED_P, \ + LANG_HOOKS_FUNCTION_DECL_DEFAULTED_INCLASS_P, \ + LANG_HOOKS_FUNCTION_DECL_DEFAULTED_OUTOFCLASS_P, \ LANG_HOOKS_GENERIC_GENERIC_PARAMETER_DECL_P, \ LANG_HOOKS_FUNCTION_PARM_EXPANDED_FROM_PACK_P, \ LANG_HOOKS_GET_GENERIC_FUNCTION_DECL, \ diff --git a/gcc/langhooks.h b/gcc/langhooks.h index 0593424..7e6eb9c 100644 --- a/gcc/langhooks.h +++ b/gcc/langhooks.h @@ -186,6 +186,14 @@ struct lang_hooks_for_decls /* Returns true if DECL is C++11 deleted special member function. */ bool (*function_decl_deleted_p) (tree); + /* Returns true if DECL is C++11 defaulted special member function + that is explicitly defaulted within the class body. */ + bool (*function_decl_defaulted_inclass_p) (tree); + + /* Returns true if DECL is C++11 defaulted special member function + that is explicitly defaulted outside the class body. */ + bool (*function_decl_defaulted_outofclass_p) (tree); + /* Returns True if the parameter is a generic parameter decl of a generic type, e.g a template template parameter for the C++ FE. */ bool (*generic_generic_parameter_decl_p) (const_tree); diff --git a/gcc/testsuite/g++.dg/debug/dwarf2/defaulted-member-function-1.C b/gcc/testsuite/g++.dg/debug/dwarf2/defaulted-member-function-1.C new file mode 100644 index 0000000..c1d107c --- /dev/null +++ b/gcc/testsuite/g++.dg/debug/dwarf2/defaulted-member-function-1.C @@ -0,0 +1,14 @@ +// { dg-do compile } +// { dg-options "-O -std=c++11 -g -dA -gno-strict-dwarf" } +// { dg-final { scan-assembler-times "0x1\[ \t\]\[^\n\]*\[ \t\]DW_AT_GNU_defaulted" 1 { xfail { powerpc-ibm-aix* } } } } + +struct Foo +{ + Foo () = default; +}; + +void +bar () +{ + Foo foo; +} diff --git a/gcc/testsuite/g++.dg/debug/dwarf2/defaulted-member-function-2.C b/gcc/testsuite/g++.dg/debug/dwarf2/defaulted-member-function-2.C new file mode 100644 index 0000000..29a08de --- /dev/null +++ b/gcc/testsuite/g++.dg/debug/dwarf2/defaulted-member-function-2.C @@ -0,0 +1,16 @@ +// { dg-do compile } +// { dg-options "-O -std=c++11 -g -dA -gno-strict-dwarf" } +// { dg-final { scan-assembler-times "0x2\[ \t\]\[^\n\]*\[ \t\]DW_AT_GNU_defaulted" 1 { xfail { powerpc-ibm-aix* } } } } + +struct Foo +{ + Foo (); +}; + +Foo::Foo () = default; + +void +bar () +{ + Foo foo; +} diff --git a/gcc/testsuite/g++.dg/debug/dwarf2/defaulted-member-function-3.C b/gcc/testsuite/g++.dg/debug/dwarf2/defaulted-member-function-3.C new file mode 100644 index 0000000..95cf7d2 --- /dev/null +++ b/gcc/testsuite/g++.dg/debug/dwarf2/defaulted-member-function-3.C @@ -0,0 +1,13 @@ +// { dg-do compile } +// { dg-options "-O -std=c++11 -g -dA -gno-strict-dwarf" } +// { dg-final { scan-assembler-not " DW_AT_GNU_defaulted" { xfail { powerpc-ibm-aix* } } } } + +struct Foo +{ +}; + +void +bar () +{ + Foo foo; +} diff --git a/include/dwarf2.def b/include/dwarf2.def index 2dfee56..4d06ce8 100644 --- a/include/dwarf2.def +++ b/include/dwarf2.def @@ -387,6 +387,8 @@ DW_AT (DW_AT_GNU_all_source_call_sites, 0x2118) DW_AT (DW_AT_GNU_macros, 0x2119) /* Attribute for C++ deleted special member functions (= delete;). */ DW_AT (DW_AT_GNU_deleted, 0x211a) +/* Attribute for C++ defaulted special member functions (= default;). */ +DW_AT (DW_AT_GNU_defaulted, 0x211b) /* Extensions for Fission. See http://gcc.gnu.org/wiki/DebugFission. */ DW_AT (DW_AT_GNU_dwo_name, 0x2130) DW_AT (DW_AT_GNU_dwo_id, 0x2131) diff --git a/include/dwarf2.h b/include/dwarf2.h index 1a145aa..d166a96 100644 --- a/include/dwarf2.h +++ b/include/dwarf2.h @@ -342,6 +342,14 @@ enum dwarf_macinfo_record_type DW_MACINFO_vendor_ext = 255 }; +/* DW_TAG_GNU_defaulted/DW_TAG_defaulted attributes. */ +enum dwarf_defaulted_attribute + { + DW_DEFAULTED_no = 0x00, + DW_DEFAULTED_in_class = 0x01, + DW_DEFAULTED_out_of_class = 0x02 + }; + /* Names and codes for new style macro information. */ enum dwarf_macro_record_type {