Message ID | 1412357525.5933.38.camel@bordewijk.wildebeest.org |
---|---|
State | New |
Headers | show |
> O. Then I was indeed wrong and defaulted does not impact ABI at all. > At least that is one worry less for the abi checkers :) As Siva mentioned, it does in fact impact the ABI. A class with a non-trivial destructor is not a POD, and affects the calling convention, so the debugger needs to know the difference. C++ ABI reference here: http://mentorembedded.github.io/cxx-abi/abi.html#return-value I've submitted a DWARF proposal to document the use of the DW_AT_artificial attribute on a default copy constructor or destructor. -cary
On Fri, 2014-10-03 at 11:41 -0700, Cary Coutant wrote: > > O. Then I was indeed wrong and defaulted does not impact ABI at all. > > At least that is one worry less for the abi checkers :) > > As Siva mentioned, it does in fact impact the ABI. A class with a > non-trivial destructor is not a POD, and affects the calling > convention, so the debugger needs to know the difference. C++ ABI > reference here: > > http://mentorembedded.github.io/cxx-abi/abi.html#return-value > > I've submitted a DWARF proposal to document the use of the > DW_AT_artificial attribute on a default copy constructor or > destructor. Thanks for that reference. I was just stepping through gdb's gdbarch_return_in_first_hidden_param_p to understand why Siva's example did indeed seem to go wrong under GDB. That code is a little hairy with all the arch specific indirections, so I am happy I can stop now :) I can adjust my patch so that it does mark the declaration with DW_AT_artificial if it is DECL_COPY_CONSTRUCTOR_P or DECL_DESTRUCTOR_P. But maybe that is probably better done as a separate patch. Or does it make sense to mark all defaulted special function members as artificial instead of having a separate attribute for it? The (small) advantage of having a separate attribute is that the consumer knows whether it was explicitly defaulted. Thanks, Mark
On 10/03/2014 02:41 PM, Cary Coutant wrote: >> O. Then I was indeed wrong and defaulted does not impact ABI at all. >> At least that is one worry less for the abi checkers :) > > As Siva mentioned, it does in fact impact the ABI. A class with a > non-trivial destructor is not a POD, and affects the calling > convention, so the debugger needs to know the difference. Yes, but defaulted does not imply trivial (though the converse is true), so knowing whether a declaration is defaulted is neither necessary nor sufficient to determine the parameter passing ABI. It would be good to represent trivial_fn_p in the DWARF. Jason
On Fri, Oct 3, 2014 at 12:45 PM, Jason Merrill <jason@redhat.com> wrote: > On 10/03/2014 02:41 PM, Cary Coutant wrote: >>> >>> O. Then I was indeed wrong and defaulted does not impact ABI at all. >>> At least that is one worry less for the abi checkers :) >> >> >> As Siva mentioned, it does in fact impact the ABI. A class with a >> non-trivial destructor is not a POD, and affects the calling >> convention, so the debugger needs to know the difference. > > > Yes, but defaulted does not imply trivial (though the converse is true), so > knowing whether a declaration is defaulted is neither necessary nor > sufficient to determine the parameter passing ABI. I understand that knowing whether a copy-ctor or a d-tor has been explicitly defaulted is not sufficient to determine the parameter passing ABI. However, why is it not necessary? I could be wrong, but doesn't the example I have given show that it is necessary? Thanks, Siva Chandra
On 10/03/2014 05:41 PM, Siva Chandra wrote: > I understand that knowing whether a copy-ctor or a d-tor has been > explicitly defaulted is not sufficient to determine the parameter > passing ABI. However, why is it not necessary? I could be wrong, but > doesn't the example I have given show that it is necessary? An implicitly declared 'tor can also be trivial. Jason
On Sat, Oct 4, 2014 at 11:14 AM, Jason Merrill <jason@redhat.com> wrote: > On 10/03/2014 05:41 PM, Siva Chandra wrote: >> >> I understand that knowing whether a copy-ctor or a d-tor has been >> explicitly defaulted is not sufficient to determine the parameter >> passing ABI. However, why is it not necessary? I could be wrong, but >> doesn't the example I have given show that it is necessary? > > An implicitly declared 'tor can also be trivial. But, the question is whether it is required to determine the parameter passing ABI. If there is no special marker to indicate that the user declared 'tor is explicitly defaulted, then GDB could (in the absence of other properties which make the 'tor non-trivial) incorrectly conclude that the the 'tor is user defined, and hence not-trivial.
On 10/06/2014 08:50 PM, Siva Chandra wrote: > On Sat, Oct 4, 2014 at 11:14 AM, Jason Merrill <jason@redhat.com> wrote: >> On 10/03/2014 05:41 PM, Siva Chandra wrote: >>> >>> I understand that knowing whether a copy-ctor or a d-tor has been >>> explicitly defaulted is not sufficient to determine the parameter >>> passing ABI. However, why is it not necessary? I could be wrong, but >>> doesn't the example I have given show that it is necessary? >> >> An implicitly declared 'tor can also be trivial. > > But, the question is whether it is required to determine the parameter > passing ABI. If there is no special marker to indicate that the user > declared 'tor is explicitly defaulted, then GDB could (in the absence > of other properties which make the 'tor non-trivial) incorrectly > conclude that the the 'tor is user defined, and hence not-trivial. I've been thinking that we should just mark the 'tor as trivial or not directly rather than hint at it. Does GDB have enough information to determine triviality if we just add defaulted info? Jason
Jason Merrill <jason@redhat.com> writes: > On 10/06/2014 08:50 PM, Siva Chandra wrote: >> On Sat, Oct 4, 2014 at 11:14 AM, Jason Merrill <jason@redhat.com> wrote: >>> On 10/03/2014 05:41 PM, Siva Chandra wrote: >>>> >>>> I understand that knowing whether a copy-ctor or a d-tor has been >>>> explicitly defaulted is not sufficient to determine the parameter >>>> passing ABI. However, why is it not necessary? I could be wrong, but >>>> doesn't the example I have given show that it is necessary? >>> >>> An implicitly declared 'tor can also be trivial. >> >> But, the question is whether it is required to determine the parameter >> passing ABI. If there is no special marker to indicate that the user >> declared 'tor is explicitly defaulted, then GDB could (in the absence >> of other properties which make the 'tor non-trivial) incorrectly >> conclude that the the 'tor is user defined, and hence not-trivial. > > I've been thinking that we should just mark the 'tor as trivial or not > directly rather than hint at it. FWIW, this would be my inclination too. I think it would make the job of the debug info consumer a lot easier. Thanks.
On Mon, 2014-10-06 at 20:55 -0400, Jason Merrill wrote: > On 10/06/2014 08:50 PM, Siva Chandra wrote: > > On Sat, Oct 4, 2014 at 11:14 AM, Jason Merrill <jason@redhat.com> wrote: > >> On 10/03/2014 05:41 PM, Siva Chandra wrote: > >>> > >>> I understand that knowing whether a copy-ctor or a d-tor has been > >>> explicitly defaulted is not sufficient to determine the parameter > >>> passing ABI. However, why is it not necessary? I could be wrong, but > >>> doesn't the example I have given show that it is necessary? > >> > >> An implicitly declared 'tor can also be trivial. > > > > But, the question is whether it is required to determine the parameter > > passing ABI. If there is no special marker to indicate that the user > > declared 'tor is explicitly defaulted, then GDB could (in the absence > > of other properties which make the 'tor non-trivial) incorrectly > > conclude that the the 'tor is user defined, and hence not-trivial. > > I've been thinking that we should just mark the 'tor as trivial or not > directly rather than hint at it. Does GDB have enough information to > determine triviality if we just add defaulted info? To be honest my original patches for a deleted/defaulted markers on special member functions was really just meant to give the consumer a way to know why GCC produced a declaration in the first place. Which I still think is useful information for the consumer to have, but certainly not enough to solve the abi problem with inferior function calls Siva was seeing. Maybe GDB has enough information/smarts, but I don't think other consumers have. So an explicit "trivial/non-trivial" marker on special member functions seems like a good idea. But looking at the definition of trivial copy constructor and trivial destructor they do look more like class concepts instead of individual constructor/destructor concepts (since they rely on properties of other members and the base class). Currently GCC doesn't output declarations unless the user declares them. So an implicit copy constructor or destructor doesn't get a DWARF class member declaration. But I don't think a consumer can conclude just from that fact that the copy constructor or destructor is trivial. Nor can it asssume they are non-trivial just because they are are respresented in DWARF. So should we always output them and add a flag value to indicate (non-trivialness). Or should we add attributes on the class itself? Taking a step back and looking at the actual function that is causing the trouble because abi/calling convention seems unclear. Which makes me wonder if the issue isn't actually with the DWARF declaration of the function that has special calling conventions. I am slightly surprised the special return value passed in rule isn't expressed in the mangling of the function name (or is it?). So the calling convention needs to be interpreted from the DWARF representation. We already add a synthetic formal parameter for "this" if necessary to be passed in. Why don't we just add a similar synthetic "return" formal parameter if that is how the function is really being invoked? That seems like a more direct way to solve the inferior function call issue. Cheers, Mark
On Mon, Oct 6, 2014 at 5:55 PM, Jason Merrill <jason@redhat.com> wrote: > On 10/06/2014 08:50 PM, Siva Chandra wrote: >> But, the question is whether it is required to determine the parameter >> passing ABI. If there is no special marker to indicate that the user >> declared 'tor is explicitly defaulted, then GDB could (in the absence >> of other properties which make the 'tor non-trivial) incorrectly >> conclude that the the 'tor is user defined, and hence not-trivial. > > I've been thinking that we should just mark the 'tor as trivial or not > directly rather than hint at it. Does GDB have enough information to > determine triviality if we just add defaulted info? Barring some incompleteness, for which patches are very close to getting committed, I believe GDB has the rest of the information. After those patches are committed, the algorithm used by GDB to determine whether a value is returned in a hidden param or not is as follows: 1. If the value is of a dynamic class (as in, has virtual bases or virtual functions), return in hidden param. 2. Else, go over all methods that are found in the DWARF: ----2a. If a method is marked artificial, ignore it. ----2b. If the method is a copy-constructor or a destructor, conclude that a pointer to the value is to be returned in the hidden first param. -------- This is because, presence of a copy-ctor or dtor which are nor artificial indicates that they were user declared and not implicit. 3. If a decision was not made in 2, do 1 and 2 for base class subobjects and non-static members. 4. If a decision was not made in 3, then conclude that it should not be passed in a hidden param. If an explicitly defaulted copy-ctor or dtor is not marked as such, step 2 is broken.
On Tue, Oct 7, 2014 at 4:05 AM, Mark Wielaard <mjw@redhat.com> wrote: > To be honest my original patches for a deleted/defaulted markers on > special member functions was really just meant to give the consumer a > way to know why GCC produced a declaration in the first place. Which I > still think is useful information for the consumer to have, but > certainly not enough to solve the abi problem with inferior function > calls Siva was seeing. Maybe GDB has enough information/smarts, but I > don't think other consumers have. So an explicit "trivial/non-trivial" > marker on special member functions seems like a good idea. > > But looking at the definition of trivial copy constructor and trivial > destructor they do look more like class concepts instead of individual > constructor/destructor concepts (since they rely on properties of other > members and the base class). Currently GCC doesn't output declarations > unless the user declares them. So an implicit copy constructor or > destructor doesn't get a DWARF class member declaration. But I don't > think a consumer can conclude just from that fact that the copy > constructor or destructor is trivial. Nor can it asssume they are > non-trivial just because they are are respresented in DWARF. So should > we always output them and add a flag value to indicate > (non-trivialness). Or should we add attributes on the class itself? I also feel that triviality of special methods is more like a class concept. Also, this concept is specified by the language. > Taking a step back and looking at the actual function that is causing > the trouble because abi/calling convention seems unclear. Which makes me > wonder if the issue isn't actually with the DWARF declaration of the > function that has special calling conventions. I am slightly surprised > the special return value passed in rule isn't expressed in the mangling > of the function name (or is it?). So the calling convention needs to be > interpreted from the DWARF representation. We already add a synthetic > formal parameter for "this" if necessary to be passed in. Why don't we > just add a similar synthetic "return" formal parameter if that is how > the function is really being invoked? That seems like a more direct way > to solve the inferior function call issue. Triviality (or not) is specified by the language. Similarly, the 'this' pointer is specified by the language. However, function calling convention is specified by the ABI. ISTR that DWARF cannot/should not describe the ABI. May be I am wrong, but if it is indeed possible to specify the ABI in DWARF, then I agree that it probably is the best solution for function call issue. Thanks, Siva Chandra
On 10/07/2014 09:36 AM, Siva Chandra wrote: > Barring some incompleteness, for which patches are very close to > getting committed, I believe GDB has the rest of the information. Interesting. It is still the case that defaulting in the class is different from defaulting outside the class, though; a function defaulted outside the class is user-provided, and therefore not trivial. But rather than encode "defaulted in the class body" (as Mark's initial patch) I'd prefer to just encode "trivial". DW_AT_artificial is for things not actually declared in the source, so using it for explicitly declared functions is incorrect. Jason
From f72525e11d08ad49d208ab75c806326871d881d7 Mon Sep 17 00:00:00 2001 From: Mark Wielaard <mjw@redhat.com> Date: Fri, 3 Oct 2014 14:44:27 +0200 Subject: [PATCH] PR debug/63240 Add DWARF representation for C++11 defaulted member function. gcc/ChangeLog * dwarf2out.c (gen_subprogram_die): When a member function is declared default then add a DW_AT_GNU_defaulted attribute. * langhooks.h (struct lang_hooks_for_decls): Add function_decl_defaulted_p langhook. * langhooks-def.h (LANG_HOOKS_FUNCTION_DECL_DEFAULTED_P): Define. (LANG_HOOKS_DECLS): Add LANG_HOOKS_FUNCTION_DECL_DEFAULTED_P. gcc/cp/ChangeLog * cp-objcp-common.h (LANG_HOOKS_FUNCTION_DECL_DEFAULTED_P): Define. (cp_function_decl_defaulted_p): New prototype. * cp-objcp-common.c (cp_function_defaulted_p): New function. gcc/testsuite/ChangeLog * g++.dg/debug/dwarf2/defaulted-member-function.C: New testcase. include/ChangeLog * dwarf2.def (DW_AT_GNU_defaulted): New attribute. --- gcc/ChangeLog | 10 ++++++++++ gcc/cp/ChangeLog | 7 +++++++ gcc/cp/cp-objcp-common.c | 10 ++++++++++ gcc/cp/cp-objcp-common.h | 3 +++ gcc/dwarf2out.c | 6 ++++++ gcc/langhooks-def.h | 2 ++ gcc/langhooks.h | 3 +++ gcc/testsuite/ChangeLog | 5 +++++ .../g++.dg/debug/dwarf2/defaulted-member-function.C | 17 +++++++++++++++++ include/ChangeLog | 5 +++++ include/dwarf2.def | 2 ++ 11 files changed, 70 insertions(+) create mode 100644 gcc/testsuite/g++.dg/debug/dwarf2/defaulted-member-function.C diff --git a/gcc/ChangeLog b/gcc/ChangeLog index dc3287b..255b1b6 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2014-10-03 Mark Wielaard <mjw@redhat.com> + + PR debug/63240 + * dwarf2out.c (gen_subprogram_die): When a member function is + declared default then add a DW_AT_GNU_defaulted attribute. + * langhooks.h (struct lang_hooks_for_decls): Add + function_decl_defaulted_p langhook. + * langhooks-def.h (LANG_HOOKS_FUNCTION_DECL_DEFAULTED_P): Define. + (LANG_HOOKS_DECLS): Add LANG_HOOKS_FUNCTION_DECL_DEFAULTED_P. + 2014-10-02 Mark Wielaard <mjw@redhat.com> PR debug/63239 diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 921f95c..d88bcd8 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2014-10-03 Mark Wielaard <mjw@redhat.com> + + PR debug/63240 + * cp-objcp-common.h (LANG_HOOKS_FUNCTION_DECL_DEFAULTED_P): Define. + (cp_function_decl_defaulted_p): New prototype. + * cp-objcp-common.c (cp_function_defaulted_p): New function. + 2014-10-02 Mark Wielaard <mjw@redhat.com> PR debug/63239 diff --git a/gcc/cp/cp-objcp-common.c b/gcc/cp/cp-objcp-common.c index 0d144ef..e668183 100644 --- a/gcc/cp/cp-objcp-common.c +++ b/gcc/cp/cp-objcp-common.c @@ -178,6 +178,16 @@ cp_function_decl_deleted_p (tree decl) && DECL_DELETED_FN (decl)); } +/* Return true if DECL is defaulted special member function. */ + +bool +cp_function_decl_defaulted_p (tree decl) +{ + return (decl + && DECL_LANG_SPECIFIC (STRIP_TEMPLATE (decl)) + && DECL_DEFAULTED_FN (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 c289774..348874f 100644 --- a/gcc/cp/cp-objcp-common.h +++ b/gcc/cp/cp-objcp-common.h @@ -28,6 +28,7 @@ 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_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 +135,8 @@ 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_P +#define LANG_HOOKS_FUNCTION_DECL_DEFAULTED_P cp_function_decl_defaulted_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 11544d8..54c2ee2 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -18305,6 +18305,12 @@ gen_subprogram_die (tree decl, dw_die_ref context_die) && (! 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_p (decl) + && (! dwarf_strict)) + add_AT_flag (subr_die, DW_AT_GNU_defaulted, 1); + /* The first time we see a member function, it is in the context of the class to which it belongs. We make sure of this by emitting the class first. The next time is the definition, which is diff --git a/gcc/langhooks-def.h b/gcc/langhooks-def.h index e5ae3e3..190a803 100644 --- a/gcc/langhooks-def.h +++ b/gcc/langhooks-def.h @@ -204,6 +204,7 @@ 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_P hook_bool_tree_false #define LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL lhd_warn_unused_global_decl #define LANG_HOOKS_WRITE_GLOBALS write_global_declarations #define LANG_HOOKS_DECL_OK_FOR_SIBCALL lhd_decl_ok_for_sibcall @@ -226,6 +227,7 @@ 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_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 32e76f9..b1138a2 100644 --- a/gcc/langhooks.h +++ b/gcc/langhooks.h @@ -169,6 +169,9 @@ 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. */ + bool (*function_decl_defaulted_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/ChangeLog b/gcc/testsuite/ChangeLog index 2a6fe3f..353a90e 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2014-10-03 Mark Wielaard <mjw@redhat.com> + + PR debug/63240 + * g++.dg/debug/dwarf2/defaulted-member-function.C: New testcase. + 2014-10-02 Mark Wielaard <mjw@redhat.com> PR debug/63239 diff --git a/gcc/testsuite/g++.dg/debug/dwarf2/defaulted-member-function.C b/gcc/testsuite/g++.dg/debug/dwarf2/defaulted-member-function.C new file mode 100644 index 0000000..635e5ba --- /dev/null +++ b/gcc/testsuite/g++.dg/debug/dwarf2/defaulted-member-function.C @@ -0,0 +1,17 @@ +// { dg-do compile } +// { dg-options "-O -std=c++11 -g -dA" } +// { dg-final { scan-assembler-times "# DW_AT_GNU_defaulted" 2 } } + +struct Foo +{ + Foo () {} + // Make copyable + Foo (const Foo&) = default; + Foo & operator=(const Foo&) = default; +}; + +void +bar () +{ + Foo foo; +} diff --git a/include/ChangeLog b/include/ChangeLog index fd6274f..e9a3a02 100644 --- a/include/ChangeLog +++ b/include/ChangeLog @@ -1,3 +1,8 @@ +2013-10-03 Mark Wielaard <mjw@redhat.com> + + PR debug/63240 + * dwarf2.def (DW_AT_GNU_defaulted): New attribute. + 2013-10-02 Mark Wielaard <mjw@redhat.com> PR debug/63239 diff --git a/include/dwarf2.def b/include/dwarf2.def index 42a8d4b..067454c 100644 --- a/include/dwarf2.def +++ b/include/dwarf2.def @@ -385,6 +385,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 function in class body (= 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) -- 1.8.3.1