This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

C++ PATCH for c++/53756 (-g and C++1y auto)


My earlier work to support return type deduction omitted support for debugging information; this patch fixes that oversight. It also corrects the mangled name of 'operator auto', which should reflect the 'auto' rather than the deduced return type.

Tested x86_64-pc-linux-gnu, applying to trunk.
commit 2b1d597e10480dfc2aefe251990cacc2af11d7cc
Author: Jason Merrill <jason@redhat.com>
Date:   Wed Nov 6 12:02:55 2013 -0500

    	PR c++/53756
    gcc/
    	* dwarf2out.c (auto_die): New static.
    	(gen_type_die_with_usage): Handle C++1y 'auto'.
    	(gen_subprogram_die): If in-class DIE had 'auto', emit type again
    	on definition.
    gcc/cp/
    	* mangle.c (write_unqualified_name): Handle operator auto.

diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c
index be3c698..add73cf 100644
--- a/gcc/cp/mangle.c
+++ b/gcc/cp/mangle.c
@@ -1231,6 +1231,9 @@ write_unqualified_name (const tree decl)
 	      fn_type = get_mostly_instantiated_function_type (decl);
 	      type = TREE_TYPE (fn_type);
 	    }
+	  else if (FNDECL_USED_AUTO (decl))
+	    type = (DECL_STRUCT_FUNCTION (decl)->language
+		    ->x_auto_return_pattern);
 	  else
 	    type = DECL_CONV_FN_TYPE (decl);
 	  write_conversion_operator_name (type);
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index 22282d8..f6efd1f 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -247,6 +247,9 @@ static GTY(()) bool cold_text_section_used = false;
 /* The default cold text section.  */
 static GTY(()) section *cold_text_section;
 
+/* The DIE for C++1y 'auto' in a function return type.  */
+static GTY(()) dw_die_ref auto_die;
+
 /* Forward declarations for functions defined in this file.  */
 
 static char *stripattributes (const char *);
@@ -17999,6 +18002,13 @@ gen_subprogram_die (tree decl, dw_die_ref context_die)
 	    add_AT_file (subr_die, DW_AT_decl_file, file_index);
 	  if (get_AT_unsigned (old_die, DW_AT_decl_line) != (unsigned) s.line)
 	    add_AT_unsigned (subr_die, DW_AT_decl_line, s.line);
+
+	  /* If the prototype had an 'auto' return type, emit the real
+	     type on the definition die.  */
+	  if (is_cxx() && debug_info_level > DINFO_LEVEL_TERSE
+	      && get_AT_ref (old_die, DW_AT_type) == auto_die)
+	    add_type_attribute (subr_die, TREE_TYPE (TREE_TYPE (decl)),
+				0, 0, context_die);
 	}
     }
   else
@@ -19820,6 +19830,25 @@ gen_type_die_with_usage (tree type, dw_die_ref context_die,
       break;
 
     default:
+      // A C++ function with deduced return type can have
+      // a TEMPLATE_TYPE_PARM named 'auto' in its type.
+      if (is_cxx ())
+	{
+	  tree name = TYPE_NAME (type);
+	  if (TREE_CODE (name) == TYPE_DECL)
+	    name = DECL_NAME (name);
+	  if (name == get_identifier ("auto"))
+	    {
+	      if (!auto_die)
+		{
+		  auto_die = new_die (DW_TAG_unspecified_type,
+				      comp_unit_die (), NULL_TREE);
+		  add_name_attribute (auto_die, "auto");
+		}
+	      equate_type_number_to_die (type, auto_die);
+	      break;
+	    }
+	}
       gcc_unreachable ();
     }
 
diff --git a/gcc/testsuite/g++.dg/cpp1y/auto-fn12.C b/gcc/testsuite/g++.dg/cpp1y/auto-fn12.C
index e4e58e8..ab4a1bb 100644
--- a/gcc/testsuite/g++.dg/cpp1y/auto-fn12.C
+++ b/gcc/testsuite/g++.dg/cpp1y/auto-fn12.C
@@ -1,5 +1,5 @@
 // { dg-options -std=c++1y }
-// { dg-final { scan-assembler "_ZN1AIiEcviEv" } }
+// { dg-final { scan-assembler "_ZN1AIiEcvDaEv" } }
 
 template <class T>
 struct A {
diff --git a/gcc/testsuite/g++.dg/cpp1y/auto-fn22.C b/gcc/testsuite/g++.dg/cpp1y/auto-fn22.C
new file mode 100644
index 0000000..f05cbb9
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/auto-fn22.C
@@ -0,0 +1,9 @@
+// { dg-options "-std=c++1y" }
+
+struct A
+{
+  operator auto();
+};
+
+// { dg-final { scan-assembler "_ZN1AcvDaEv" } }
+A::operator auto() { return 42; }
diff --git a/gcc/testsuite/g++.dg/debug/dwarf2/auto1.C b/gcc/testsuite/g++.dg/debug/dwarf2/auto1.C
new file mode 100644
index 0000000..188ca11
--- /dev/null
+++ b/gcc/testsuite/g++.dg/debug/dwarf2/auto1.C
@@ -0,0 +1,30 @@
+// PR c++/53756
+// { dg-options "-std=c++1y -g -dA -fno-debug-types-section" }
+// We're looking for something like
+
+// .uleb128 0x3    # (DIE (0x33) DW_TAG_subprogram)
+// .ascii "a1\0"   # DW_AT_name
+// .long   0x4c    # DW_AT_type
+//...
+// .uleb128 0x5    # (DIE (0x4c) DW_TAG_unspecified_type)
+// .long   .LASF6  # DW_AT_name: "auto"
+//...
+// .uleb128 0x7    # (DIE (0x57) DW_TAG_subprogram)
+// .long   0x33    # DW_AT_specification
+// .long   0x87    # DW_AT_type
+//...
+// .uleb128 0x9    # (DIE (0x87) DW_TAG_base_type)
+// .ascii "int\0"  # DW_AT_name
+
+// { dg-final { scan-assembler "a1.*(0x\[0-9a-f\]+)\[ \t\]*# DW_AT_type.*\\1. DW_TAG_unspecified_type.*DW_AT_specification\[\n\r\]{1,2}\[^\n\r\]*(0x\[0-9a-f\]+)\[ \t\]*# DW_AT_type.*\\2. DW_TAG_base_type" } }
+
+struct A
+{
+  auto a1 () { return 42; }
+};
+
+int main()
+{
+  A a;
+  a.a1();
+}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]