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]

[PATCH 1/2] PR debug/38757 gcc does not emit DW_LANG_C99.


On Thu, Nov 13, 2014 at 02:19:57PM +0100, Richard Biener wrote:
> I'm fine with the string solution as well.  Just properly transfer whatever
> info you want through the translation unit decl and LTO stream it.

OK, strings it is then. Here are two patches. The first makes the change
to the lang_hook.name to include the std version for GNU C and GNU C++ and
updates all users. It merges the TRANSLATION_UNIT_LANGUAGE in dwarf2out.c
It uses this to set DW_LANG_C99 when appropriate.

The second patch adds support for C11, C++11 and C++14 as outlined
in the DWARFv5 DRAFT http://dwarfstd.org/doc/dwarf5.20141029.pdf

Note that this does not add DW_LANG_C_plus_plus_03 which I believe
is a mistake: http://thread.gmane.org/gmane.comp.standards.dwarf/218
C++03 isn't actually a new language standard, just C++98 plus some
new DRs, but no actual language changes.

The first patch adds two new tests, which PASS and has no regressions.
The second patch adds four new tests, which PASS, but break the C++
prettyprinters. You need a simple patch to GDB to get them working
again (just add the new dwarf2.h and use the new constants). It might
be better to wait with the second patch till I have patched GDB/binutils,
elfutils and valgrind to accept the new values. I'll submit those ASAP.

OK to commit the first patch now and the second patch as soon as
my patches to GDB/binutils, elfutils and valgrind are accepted upstream?

Thanks,

Mark

<--->

For C and C++ add the language standard version in use to lang_hooks.name.
Change users of lang_hook.name to check with strncmp first for "GNU C++"
then for "GNU C". In dwarf2out.c output the DW_LANG_C version from the
lang_hooks.name and merge any LTO TRANSLATION_UNIT_LANGUAGE found. Adds
two testcases to dwarf2.exp to check the right DWARF DW_AT_language is set
on the compile_unit depending on the -std=c89 or -std=c99 setting.

gcc/c-family/ChangeLog

2014-11-20  Mark Wielaard  <mjw@redhat.com>

	PR debug/38757
	* c-opts.c (set_std_c89): Set lang_hooks.name.
	(set_std_c99): Likewise.
	(set_std_c11): Likewise.
	(set_std_cxx98): Likewise.
	(set_std_cxx11): Likewise.
	(set_std_cxx14): Likewise.
	(set_std_cxx1z): Likewise.

gcc/ChangeLog

2014-11-20  Mark Wielaard  <mjw@redhat.com>

	PR debug/38757
	* config/avr/avr-c.c (avr_cpu_cpp_builtins): Use strncmp to
	check lang_hooks.name.
	* config/darwin.c (darwin_file_end): Likewise.
	(darwin_override_options): Likewise.
	* config/ia64/ia64.c (ia64_struct_retval_addr_is_first_parm_p):
	Likewise.
	* config/rs6000/rs6000.c (rs6000_output_function_epilogue):
	Likewise.
	* dbxout.c (get_lang_number): Likewise.
	(dbxout_type): Likewise.
	(dbxout_symbol_location): Likewise.
	* dwarf2out.c (add_prototyped_attribute): Add DW_AT_prototype
	also for DW_LANG_{C,C99,ObjC}.
	(highest_c_language): New function.
	(gen_compile_unit_die): Call highest_c_language to merge LTO
	TRANSLATION_UNIT_LANGUAGE. Use strncmp lang_hooks.name to
        determine if DW_LANG_C99 or DW_LANG_C89 should be returned.
	* fold-const.c (fold_cond_expr_with_comparison): Use strncmp
	to check lang_hooks.name.
	* langhooks.h (struct lang_hooks): Add version comment to name.
	* vmsdbgout.c (vmsdbgout_init): Use strncmp to check
	lang_hooks.name.
---
 gcc/ChangeLog                                | 26 ++++++++++++++
 gcc/c-family/ChangeLog                       | 11 ++++++
 gcc/c-family/c-opts.c                        |  7 ++++
 gcc/config/avr/avr-c.c                       |  3 +-
 gcc/config/darwin.c                          |  4 +--
 gcc/config/ia64/ia64.c                       |  2 +-
 gcc/config/rs6000/rs6000.c                   | 11 +++---
 gcc/dbxout.c                                 | 10 +++---
 gcc/dwarf2out.c                              | 53 ++++++++++++++++++++++++----
 gcc/fold-const.c                             |  2 +-
 gcc/langhooks.h                              |  3 +-
 gcc/testsuite/ChangeLog                      |  6 ++++
 gcc/testsuite/gcc.dg/debug/dwarf2/lang-c89.c |  6 ++++
 gcc/testsuite/gcc.dg/debug/dwarf2/lang-c99.c |  6 ++++
 gcc/vmsdbgout.c                              |  6 ++--
 15 files changed, 131 insertions(+), 25 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/debug/dwarf2/lang-c89.c
 create mode 100644 gcc/testsuite/gcc.dg/debug/dwarf2/lang-c99.c

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 428725b..222558d 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,29 @@
+2014-11-20  Mark Wielaard  <mjw@redhat.com>
+
+	PR debug/38757
+	* config/avr/avr-c.c (avr_cpu_cpp_builtins): Use strncmp to
+	check lang_hooks.name.
+	* config/darwin.c (darwin_file_end): Likewise.
+	(darwin_override_options): Likewise.
+	* config/ia64/ia64.c (ia64_struct_retval_addr_is_first_parm_p):
+	Likewise.
+	* config/rs6000/rs6000.c (rs6000_output_function_epilogue):
+	Likewise.
+	* dbxout.c (get_lang_number): Likewise.
+	(dbxout_type): Likewise.
+	(dbxout_symbol_location): Likewise.
+	* dwarf2out.c (add_prototyped_attribute): Add DW_AT_prototype
+	also for DW_LANG_{C,C99,ObjC}.
+	(highest_c_language): New function.
+	(gen_compile_unit_die): Call highest_c_language to merge LTO
+	TRANSLATION_UNIT_LANGUAGE. Use strncmp lang_hooks.name to
+	determine if DW_LANG_C99 or DW_LANG_C89 should be returned.
+	* fold-const.c (fold_cond_expr_with_comparison): Use strncmp
+	to check lang_hooks.name.
+	* langhooks.h (struct lang_hooks): Add version comment to name.
+	* vmsdbgout.c (vmsdbgout_init): Use strncmp to check
+	lang_hooks.name.
+
 2014-11-12  Marek Polacek  <polacek@redhat.com>
 
 	* fold-const.c (fold_binary_loc): Don't fold if the result
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog
index 4eb90fc..f434085 100644
--- a/gcc/c-family/ChangeLog
+++ b/gcc/c-family/ChangeLog
@@ -1,3 +1,14 @@
+2014-11-20  Mark Wielaard  <mjw@redhat.com>
+
+	PR debug/38757
+	* c-opts.c (set_std_c89): Set lang_hooks.name.
+	(set_std_c99): Likewise.
+	(set_std_c11): Likewise.
+	(set_std_cxx98): Likewise.
+	(set_std_cxx11): Likewise.
+	(set_std_cxx14): Likewise.
+	(set_std_cxx1z): Likewise.
+
 2014-11-12  Joseph Myers  <joseph@codesourcery.com>
 
 	* c-cppbuiltin.c (c_cpp_builtins_optimize_pragma): Define and
diff --git a/gcc/c-family/c-opts.c b/gcc/c-family/c-opts.c
index 000fdd2..08a36f0 100644
--- a/gcc/c-family/c-opts.c
+++ b/gcc/c-family/c-opts.c
@@ -1450,6 +1450,7 @@ set_std_c89 (int c94, int iso)
   flag_isoc94 = c94;
   flag_isoc99 = 0;
   flag_isoc11 = 0;
+  lang_hooks.name = "GNU C89";
 }
 
 /* Set the C 99 standard (without GNU extensions if ISO).  */
@@ -1463,6 +1464,7 @@ set_std_c99 (int iso)
   flag_isoc11 = 0;
   flag_isoc99 = 1;
   flag_isoc94 = 1;
+  lang_hooks.name = "GNU C99";
 }
 
 /* Set the C 11 standard (without GNU extensions if ISO).  */
@@ -1476,6 +1478,7 @@ set_std_c11 (int iso)
   flag_isoc11 = 1;
   flag_isoc99 = 1;
   flag_isoc94 = 1;
+  lang_hooks.name = "GNU C11";
 }
 
 /* Set the C++ 98 standard (without GNU extensions if ISO).  */
@@ -1487,6 +1490,7 @@ set_std_cxx98 (int iso)
   flag_no_nonansi_builtin = iso;
   flag_iso = iso;
   cxx_dialect = cxx98;
+  lang_hooks.name = "GNU C++98";
 }
 
 /* Set the C++ 2011 standard (without GNU extensions if ISO).  */
@@ -1501,6 +1505,7 @@ set_std_cxx11 (int iso)
   flag_isoc94 = 1;
   flag_isoc99 = 1;
   cxx_dialect = cxx11;
+  lang_hooks.name = "GNU C++11";
 }
 
 /* Set the C++ 2014 draft standard (without GNU extensions if ISO).  */
@@ -1515,6 +1520,7 @@ set_std_cxx14 (int iso)
   flag_isoc94 = 1;
   flag_isoc99 = 1;
   cxx_dialect = cxx14;
+  lang_hooks.name = "GNU C++14";
 }
 
 /* Set the C++ 201z draft standard (without GNU extensions if ISO).  */
@@ -1530,6 +1536,7 @@ set_std_cxx1z (int iso)
   flag_isoc99 = 1;
   flag_isoc11 = 1;
   cxx_dialect = cxx1z;
+  lang_hooks.name = "GNU C++14"; /* Pretend C++14 till standarization.  */
 }
 
 /* Args to -d specify what to dump.  Silently ignore
diff --git a/gcc/config/avr/avr-c.c b/gcc/config/avr/avr-c.c
index 13ece98..081bf09 100644
--- a/gcc/config/avr/avr-c.c
+++ b/gcc/config/avr/avr-c.c
@@ -386,7 +386,8 @@ avr_cpu_cpp_builtins (struct cpp_reader *pfile)
      (as mentioned in ISO/IEC DTR 18037; Annex F.2) which is not
      implemented in GCC up to now.  */
 
-  if (!strcmp (lang_hooks.name, "GNU C"))
+  if (strncmp (lang_hooks.name, "GNU C", 5) == 0
+      && strncmp (lang_hooks.name, "GNU C++", 7) != 0)
     {
       for (i = 0; i < ADDR_SPACE_COUNT; i++)
         if (!ADDR_SPACE_GENERIC_P (i)
diff --git a/gcc/config/darwin.c b/gcc/config/darwin.c
index a201a74..80eb272 100644
--- a/gcc/config/darwin.c
+++ b/gcc/config/darwin.c
@@ -2909,7 +2909,7 @@ darwin_file_end (void)
      }
 
   machopic_finish (asm_out_file);
-  if (strcmp (lang_hooks.name, "GNU C++") == 0)
+  if (strncmp (lang_hooks.name, "GNU C++", 7) == 0)
     {
       switch_to_section (darwin_sections[constructor_section]);
       switch_to_section (darwin_sections[destructor_section]);
@@ -3162,7 +3162,7 @@ darwin_override_options (void)
   if (flag_mkernel || flag_apple_kext)
     {
       /* -mkernel implies -fapple-kext for C++ */
-      if (strcmp (lang_hooks.name, "GNU C++") == 0)
+      if (strncmp (lang_hooks.name, "GNU C++", 7) == 0)
 	flag_apple_kext = 1;
 
       flag_no_common = 1;
diff --git a/gcc/config/ia64/ia64.c b/gcc/config/ia64/ia64.c
index f896e10..65f7a21 100644
--- a/gcc/config/ia64/ia64.c
+++ b/gcc/config/ia64/ia64.c
@@ -10753,7 +10753,7 @@ ia64_struct_retval_addr_is_first_parm_p (tree fntype)
 	  && ret_type
 	  && TYPE_MODE (ret_type) == BLKmode 
 	  && TREE_ADDRESSABLE (ret_type)
-	  && strcmp (lang_hooks.name, "GNU C++") == 0);
+	  && strncmp (lang_hooks.name, "GNU C++", 7) == 0);
 }
 
 /* Output the assembler code for a thunk function.  THUNK_DECL is the
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 336dd43..6ae06dc 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -25174,8 +25174,12 @@ rs6000_output_function_epilogue (FILE *file,
 	 C is 0.  Fortran is 1.  Pascal is 2.  Ada is 3.  C++ is 9.
 	 Java is 13.  Objective-C is 14.  Objective-C++ isn't assigned
 	 a number, so for now use 9.  LTO and Go aren't assigned numbers
-	 either, so for now use 0.  */
-      if (! strcmp (language_string, "GNU C")
+	 either, so for now use 0.  Match GNU C++ first, since it needs to
+	 be compared with strncmp, like GNU C, which has the same prefix.  */
+      if (! strncmp (language_string, "GNU C++", 7)
+	       || ! strcmp (language_string, "GNU Objective-C++"))
+	i = 9;
+      else if (! strncmp (language_string, "GNU C", 5)
 	  || ! strcmp (language_string, "GNU GIMPLE")
 	  || ! strcmp (language_string, "GNU Go"))
 	i = 0;
@@ -25186,9 +25190,6 @@ rs6000_output_function_epilogue (FILE *file,
 	i = 2;
       else if (! strcmp (language_string, "GNU Ada"))
 	i = 3;
-      else if (! strcmp (language_string, "GNU C++")
-	       || ! strcmp (language_string, "GNU Objective-C++"))
-	i = 9;
       else if (! strcmp (language_string, "GNU Java"))
 	i = 13;
       else if (! strcmp (language_string, "GNU Objective-C"))
diff --git a/gcc/dbxout.c b/gcc/dbxout.c
index aa15a39..7811eec 100644
--- a/gcc/dbxout.c
+++ b/gcc/dbxout.c
@@ -947,10 +947,10 @@ get_lang_number (void)
 {
   const char *language_string = lang_hooks.name;
 
-  if (strcmp (language_string, "GNU C") == 0)
-    return N_SO_C;
-  else if (strcmp (language_string, "GNU C++") == 0)
+  if (strncmp (language_string, "GNU C++", 7) == 0)
     return N_SO_CC;
+  else if (strncmp (language_string, "GNU C", 5) == 0)
+    return N_SO_C;
   else if (strcmp (language_string, "GNU F77") == 0)
     return N_SO_FORTRAN;
   else if (strcmp (language_string, "GNU Fortran") == 0)
@@ -2167,7 +2167,7 @@ dbxout_type (tree type, int full)
 				   access == access_protected_node
 				   ? '1' :'0');
 		    if (BINFO_VIRTUAL_P (child)
-			&& (strcmp (lang_hooks.name, "GNU C++") == 0
+			&& (strncmp (lang_hooks.name, "GNU C++", 7) == 0
 			    || strcmp (lang_hooks.name, "GNU Objective-C++") == 0))
 		      /* For a virtual base, print the (negative)
 		     	 offset within the vtable where we must look
@@ -3028,7 +3028,7 @@ dbxout_symbol_location (tree decl, tree type, const char *suffix, rtx home)
 	     we rely on the fact that error_mark_node initializers always
 	     end up in bss for C++ and never end up in bss for C.  */
 	  if (DECL_INITIAL (decl) == 0
-	      || (!strcmp (lang_hooks.name, "GNU C++")
+	      || (!strncmp (lang_hooks.name, "GNU C++", 7)
 		  && DECL_INITIAL (decl) == error_mark_node))
 	    {
 	      int offs;
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index b16883f..7844f33 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -16741,9 +16741,18 @@ add_bit_size_attribute (dw_die_ref die, tree decl)
 static inline void
 add_prototyped_attribute (dw_die_ref die, tree func_type)
 {
-  if (get_AT_unsigned (comp_unit_die (), DW_AT_language) == DW_LANG_C89
-      && prototype_p (func_type))
-    add_AT_flag (die, DW_AT_prototyped, 1);
+  switch (get_AT_unsigned (comp_unit_die (), DW_AT_language))
+    {
+    case DW_LANG_C:
+    case DW_LANG_C89:
+    case DW_LANG_C99:
+    case DW_LANG_ObjC:
+      if (prototype_p (func_type))
+	add_AT_flag (die, DW_AT_prototyped, 1);
+      break;
+    default:
+      break;
+    }
 }
 
 /* Add an 'abstract_origin' attribute below a given DIE.  The DIE is found
@@ -19503,6 +19512,30 @@ gen_producer_string (void)
   return producer;
 }
 
+/* Given a C and/or C++ language/version string return the "highest".
+   C++ is assumed to be "higher" than C in this case.  Used for merging
+   LTO translation unit languages.  */
+static const char *
+highest_c_language (const char *lang1, const char *lang2)
+{
+  if (strcmp ("GNU C++14", lang1) == 0 || strcmp ("GNU C++14", lang2) == 0)
+    return "GNU C++14";
+  if (strcmp ("GNU C++11", lang1) == 0 || strcmp ("GNU C++11", lang2) == 0)
+    return "GNU C++11";
+  if (strcmp ("GNU C++98", lang1) == 0 || strcmp ("GNU C++98", lang2) == 0)
+    return "GNU C++98";
+
+  if (strcmp ("GNU C11", lang1) == 0 || strcmp ("GNU C11", lang2) == 0)
+    return "GNU C11";
+  if (strcmp ("GNU C99", lang1) == 0 || strcmp ("GNU C99", lang2) == 0)
+    return "GNU C99";
+  if (strcmp ("GNU C89", lang1) == 0 || strcmp ("GNU C89", lang2) == 0)
+    return "GNU C89";
+
+  gcc_unreachable ();
+}
+
+
 /* Generate the DIE for the compilation unit.  */
 
 static dw_die_ref
@@ -19543,7 +19576,8 @@ gen_compile_unit_die (const char *filename)
 	  else if (strncmp (common_lang, "GNU C", 5) == 0
 		    && strncmp (TRANSLATION_UNIT_LANGUAGE (t), "GNU C", 5) == 0)
 	    /* Mixing C and C++ is ok, use C++ in that case.  */
-	    common_lang = "GNU C++";
+	    common_lang = highest_c_language (common_lang,
+					      TRANSLATION_UNIT_LANGUAGE (t));
 	  else
 	    {
 	      /* Fall back to C.  */
@@ -19556,9 +19590,16 @@ gen_compile_unit_die (const char *filename)
 	language_string = common_lang;
     }
 
-  language = DW_LANG_C89;
-  if (strcmp (language_string, "GNU C++") == 0)
+  language = DW_LANG_C;
+  if (strncmp (language_string, "GNU C++", 7) == 0)
     language = DW_LANG_C_plus_plus;
+  else if (strncmp (language_string, "GNU C", 5) == 0)
+    {
+      language = DW_LANG_C89;
+      if (dwarf_version >= 3 || !dwarf_strict)
+	if (strcmp (language_string, "GNU C99") == 0)
+	  language = DW_LANG_C99;
+    }
   else if (strcmp (language_string, "GNU F77") == 0)
     language = DW_LANG_Fortran77;
   else if (strcmp (language_string, "GNU Pascal") == 0)
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index 4321b1e..e4d6ac2 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -4727,7 +4727,7 @@ fold_cond_expr_with_comparison (location_t loc, tree type,
 	 as an lvalue in the C++ front-end.  PR c++/19199.  */
       && (in_gimple_form
 	  || VECTOR_TYPE_P (type)
-	  || (strcmp (lang_hooks.name, "GNU C++") != 0
+	  || (strncmp (lang_hooks.name, "GNU C++", 7) != 0
 	      && strcmp (lang_hooks.name, "GNU Objective-C++") != 0)
 	  || ! maybe_lvalue_p (arg1)
 	  || ! maybe_lvalue_p (arg2)))
diff --git a/gcc/langhooks.h b/gcc/langhooks.h
index 84449bf..37c2d2a 100644
--- a/gcc/langhooks.h
+++ b/gcc/langhooks.h
@@ -261,7 +261,8 @@ struct lang_hooks_for_lto
 
 struct lang_hooks
 {
-  /* String identifying the front end.  e.g. "GNU C++".  */
+  /* String identifying the front end.  e.g. "GNU C++".
+     Might include language version being used.  */
   const char *name;
 
   /* sizeof (struct lang_identifier), so make_node () creates
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 1c69805..9b29745 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2014-11-20  Mark Wielaard  <mjw@redhat.com>
+
+	PR debug/38757
+	* gcc.dg/debug/dwarf2/lang-c89.c: New test.
+	* gcc.dg/debug/dwarf2/lang-c99.c: Likewise.
+
 2014-11-12  Marek Polacek  <polacek@redhat.com>
 
 	* lib/gcc-dg.exp (${tool}_load): Call prune_file_path instead
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/lang-c89.c b/gcc/testsuite/gcc.dg/debug/dwarf2/lang-c89.c
new file mode 100644
index 0000000..6292cf8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/lang-c89.c
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-options "-O -std=c89 -g -dA" } */
+/* DW_LANG_C89 = 0x0001 */
+/* { dg-final { scan-assembler "0x1.*DW_AT_language" } } */
+
+int version;
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/lang-c99.c b/gcc/testsuite/gcc.dg/debug/dwarf2/lang-c99.c
new file mode 100644
index 0000000..d09d316
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/lang-c99.c
@@ -0,0 +1,6 @@
+// { dg-do compile }
+// { dg-options "-O -std=c99 -gdwarf-3 -dA" }
+// DW_LANG_C99 = 0x000c
+// { dg-final { scan-assembler "0xc.*DW_AT_language" } } */
+
+int version;
diff --git a/gcc/vmsdbgout.c b/gcc/vmsdbgout.c
index f2734ca..0f5d344 100644
--- a/gcc/vmsdbgout.c
+++ b/gcc/vmsdbgout.c
@@ -1460,10 +1460,10 @@ vmsdbgout_init (const char *filename)
 
   lookup_filename (primary_filename);
 
-  if (!strcmp (language_string, "GNU C"))
-    module_language = DST_K_C;
-  else if (!strcmp (language_string, "GNU C++"))
+  if (!strncmp (language_string, "GNU C++", 7))
     module_language = DST_K_CXX;
+  else if (!strncmp (language_string, "GNU C", 5))
+    module_language = DST_K_C;
   else if (!strcmp (language_string, "GNU Ada"))
     module_language = DST_K_ADA;
   else if (!strcmp (language_string, "GNU F77"))
-- 
1.8.3.1


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