diff mbox

[1/2] PR debug/63239 Add DWARF representation for C++11 deleted member function.

Message ID 1412341922-7891-1-git-send-email-mjw@redhat.com
State New
Headers show

Commit Message

Mark Wielaard Oct. 3, 2014, 1:12 p.m. UTC
Currently we output a declaration of the explicitly deleted function
in DWARF. That seems wrong. An alternative to adding an attribute would
be to just not output the declaration. But that is also confusing since
then it looks precisely the same as an class that has that special
function implicitly defined, since we don't output a declaration for
such implicitly defined special functions either. So this implementation
defines a new attribute DW_AT_GNU_deleted that gets added to the
declaration.

include/ChangeLog

	* dwarf2.def (DW_AT_GNU_deleted): New attribute.

gcc/ChangeLog

	* dwarf2out.c (gen_subprogram_die): When a member function is
	explicitly deleted then add a DW_AT_GNU_deleted attribute.
	* langhooks.h (struct lang_hooks_for_decls): Add
	function_decl_deleted_p langhook.
	* langhooks-def.h (LANG_HOOKS_FUNCTION_DECL_DELETED_P): Define.
	(LANG_HOOKS_DECLS): Add LANG_HOOKS_FUNCTION_DECL_DELETED_P.

gcc/cp/ChangeLog

	* cp-objcp-common.h (LANG_HOOKS_FUNCTION_DECL_DELETED_P): Define.
	(cp_function_decl_deleted_p): New prototype.
	* cp-objcp-common.c (cp_function_deleted_p): New function.

gcc/testsuite/ChangeLog

	* g++.dg/debug/dwarf2/deleted-member-function.C: New testcase.
---
 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/deleted-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/deleted-member-function.C

Comments

Jason Merrill Oct. 3, 2014, 2:15 p.m. UTC | #1
OK.

Jason
Andreas Schwab Oct. 6, 2014, 7:38 a.m. UTC | #2
Mark Wielaard <mjw@redhat.com> writes:

> diff --git a/gcc/testsuite/g++.dg/debug/dwarf2/deleted-member-function.C b/gcc/testsuite/g++.dg/debug/dwarf2/deleted-member-function.C
> new file mode 100644
> index 0000000..4cc77e6
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/debug/dwarf2/deleted-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_deleted" 2 } }

$ grep DW_AT_GNU_deleted deleted-member-function.s
                        // DW_AT_GNU_deleted
                        // DW_AT_GNU_deleted
        .uleb128 0x211a // (DW_AT_GNU_deleted)
        .uleb128 0x211a // (DW_AT_GNU_deleted)

Andreas.
Mark Wielaard Oct. 6, 2014, 7:54 a.m. UTC | #3
On Mon, 2014-10-06 at 09:38 +0200, Andreas Schwab wrote:
> Mark Wielaard <mjw@redhat.com> writes:
> 
> > diff --git a/gcc/testsuite/g++.dg/debug/dwarf2/deleted-member-function.C b/gcc/testsuite/g++.dg/debug/dwarf2/deleted-member-function.C
> > new file mode 100644
> > index 0000000..4cc77e6
> > --- /dev/null
> > +++ b/gcc/testsuite/g++.dg/debug/dwarf2/deleted-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_deleted" 2 } }
> 
> $ grep DW_AT_GNU_deleted deleted-member-function.s
>                         // DW_AT_GNU_deleted
>                         // DW_AT_GNU_deleted
>         .uleb128 0x211a // (DW_AT_GNU_deleted)
>         .uleb128 0x211a // (DW_AT_GNU_deleted)

With gcc master this testcase gives:

$ grep DW_AT_GNU_deleted deleted-member-function.s
			# DW_AT_GNU_deleted
			# DW_AT_GNU_deleted
	.uleb128 0x211a	# (DW_AT_GNU_deleted)
	.uleb128 0x211a	# (DW_AT_GNU_deleted)

Somehow in your version the # comment turned into // ?

Just removing the # prefix (but keeping the space) from
scan-assembler-times should work for both our cases. I just don't know
why our .s outputs look different. If it is something that can be fixed
through setting a dg-options that would be preferable I think.

Cheers,

Mark
Steven Bosscher Oct. 6, 2014, 8:03 a.m. UTC | #4
On Mon, Oct 6, 2014 at 9:54 AM, Mark Wielaard wrote:
> Just removing the # prefix (but keeping the space) from
> scan-assembler-times should work for both our cases. I just don't know
> why our .s outputs look different.

Wild guess: different comment marker in the target's assembly language?

Ciao!
Steven
Rainer Orth Oct. 8, 2014, 8:56 a.m. UTC | #5
Steven Bosscher <stevenb.gcc@gmail.com> writes:

> On Mon, Oct 6, 2014 at 9:54 AM, Mark Wielaard wrote:
>> Just removing the # prefix (but keeping the space) from
>> scan-assembler-times should work for both our cases. I just don't know
>> why our .s outputs look different.
>
> Wild guess: different comment marker in the target's assembly language?

True: on Solaris/x86 with /bin/as, I have

                        / DW_AT_GNU_deleted

on Solaris/SPARC with /bin/as, it's

        .byte   0x1     ! DW_AT_GNU_deleted

instead, and probably even more others on different platforms.

	Rainer
diff mbox

Patch

diff --git a/gcc/cp/cp-objcp-common.c b/gcc/cp/cp-objcp-common.c
index 0c50f40..0d144ef 100644
--- a/gcc/cp/cp-objcp-common.c
+++ b/gcc/cp/cp-objcp-common.c
@@ -168,6 +168,16 @@  cp_function_decl_explicit_p (tree decl)
 	  && DECL_NONCONVERTING_P (decl));
 }
 
+/* Return true if DECL is deleted special member function.  */
+
+bool
+cp_function_decl_deleted_p (tree decl)
+{
+  return (decl
+	  && DECL_LANG_SPECIFIC (STRIP_TEMPLATE (decl))
+	  && DECL_DELETED_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 246800e..c289774 100644
--- a/gcc/cp/cp-objcp-common.h
+++ b/gcc/cp/cp-objcp-common.h
@@ -27,6 +27,7 @@  extern tree objcp_tsubst_copy_and_build (tree, tree, tsubst_flags_t,
 					 tree, bool);
 
 extern bool cp_function_decl_explicit_p (tree decl);
+extern bool cp_function_decl_deleted_p (tree decl);
 extern void cp_common_init_ts (void);
 
 /* Lang hooks that are shared between C++ and ObjC++ are defined here.  Hooks
@@ -131,6 +132,8 @@  extern void cp_common_init_ts (void);
 #define LANG_HOOKS_GIMPLIFY_EXPR cp_gimplify_expr
 #undef LANG_HOOKS_FUNCTION_DECL_EXPLICIT_P
 #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_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 b5fcfa4..11544d8 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -18299,6 +18299,12 @@  gen_subprogram_die (tree decl, dw_die_ref context_die)
 	      && (dwarf_version >= 3 || !dwarf_strict))
 	    add_AT_flag (subr_die, DW_AT_explicit, 1);
 
+	  /* If this is a C++11 deleted special function member then generate
+	     a DW_AT_GNU_deleted attribute.  */
+	  if (lang_hooks.decls.function_decl_deleted_p (decl)
+	      && (! dwarf_strict))
+	    add_AT_flag (subr_die, DW_AT_GNU_deleted, 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 e77d2d9..e5ae3e3 100644
--- a/gcc/langhooks-def.h
+++ b/gcc/langhooks-def.h
@@ -203,6 +203,7 @@  extern tree lhd_make_node (enum tree_code);
 #define LANG_HOOKS_PUSHDECL	pushdecl
 #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_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
@@ -224,6 +225,7 @@  extern tree lhd_make_node (enum tree_code);
   LANG_HOOKS_PUSHDECL, \
   LANG_HOOKS_GETDECLS, \
   LANG_HOOKS_FUNCTION_DECL_EXPLICIT_P, \
+  LANG_HOOKS_FUNCTION_DECL_DELETED_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 72fa85e..32e76f9 100644
--- a/gcc/langhooks.h
+++ b/gcc/langhooks.h
@@ -166,6 +166,9 @@  struct lang_hooks_for_decls
   /* Returns true if DECL is explicit member function.  */
   bool (*function_decl_explicit_p) (tree);
 
+  /* Returns true if DECL is C++11 deleted special member function.  */
+  bool (*function_decl_deleted_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/deleted-member-function.C b/gcc/testsuite/g++.dg/debug/dwarf2/deleted-member-function.C
new file mode 100644
index 0000000..4cc77e6
--- /dev/null
+++ b/gcc/testsuite/g++.dg/debug/dwarf2/deleted-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_deleted" 2 } }
+
+struct Foo
+{
+  Foo () {}
+  // Make non-copyable
+  Foo (const Foo&) = delete;
+  Foo & operator=(const Foo&) = delete;
+};
+
+void
+bar ()
+{
+  Foo foo;
+}
diff --git a/include/dwarf2.def b/include/dwarf2.def
index 71a37b3..42a8d4b 100644
--- a/include/dwarf2.def
+++ b/include/dwarf2.def
@@ -383,6 +383,8 @@  DW_AT (DW_AT_GNU_all_call_sites, 0x2117)
 DW_AT (DW_AT_GNU_all_source_call_sites, 0x2118)
 /* Section offset into .debug_macro section.  */
 DW_AT (DW_AT_GNU_macros, 0x2119)
+/* Attribute for C++ deleted special member functions (= delete;).  */
+DW_AT (DW_AT_GNU_deleted, 0x211a)
 /* 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)