[3/3] Fix PR libcc1/113977

Message ID 20240226-gdb-compile-align-v1-3-0f95d6435299@tromey.com
State New
Headers
Series Fix libcc1 failure |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_gcc_build--master-aarch64 success Testing passed
linaro-tcwg-bot/tcwg_gcc_build--master-arm success Testing passed
linaro-tcwg-bot/tcwg_gcc_check--master-arm success Testing passed
linaro-tcwg-bot/tcwg_gcc_check--master-aarch64 success Testing passed

Commit Message

Tom Tromey Feb. 27, 2024, 3:12 a.m. UTC
  PR libcc1/113977 points out a case where a simple expression is
rejected with a compiler error message.  The bug here is that gdb does
not inform the plugin of the correct alignment -- in fact, there is no
way to do that.

This patch adds a new method to allow the alignment to be set, and
bumps the C front end protocol version.

It also includes some updates to various comments in 'include', done
here to simplify the merge to binutils-gdb.

include/ChangeLog
2024-02-26  Tom Tromey  <tom@tromey.com>

	* gcc-cp-interface.h (gcc_cp_fe_context_function): Update
	comment.
	* gcc-c-interface.h (enum gcc_c_api_version) <GCC_C_FE_VERSION_2>:
	New constant.
	(gcc_c_fe_context_function): Update comment.
	* gcc-c-fe.def (finish_record_with_alignment): New method.
	Update documentation.

libcc1/ChangeLog
2024-02-26  Tom Tromey  <tom@tromey.com>

	PR libcc1/113977
	* libcc1plugin.cc (plugin_finish_record_or_union): New function.
	(plugin_finish_record_or_union): Rewrite.
	(plugin_init): Use GCC_C_FE_VERSION_2.
	* libcc1.cc (c_vtable): Use GCC_C_FE_VERSION_2.
	(gcc_c_fe_context): Check for GCC_C_FE_VERSION_2.
---
 include/ChangeLog          | 10 ++++++++++
 include/gcc-c-fe.def       | 13 ++++++++++++-
 include/gcc-c-interface.h  | 11 +++++++++--
 include/gcc-cp-interface.h |  6 +++++-
 libcc1/ChangeLog           |  9 +++++++++
 libcc1/libcc1.cc           |  5 +++--
 libcc1/libcc1plugin.cc     | 26 ++++++++++++++++++--------
 7 files changed, 66 insertions(+), 14 deletions(-)
  

Patch

diff --git a/include/ChangeLog b/include/ChangeLog
index 8bfaec6faa1..4c8b5b28039 100644
--- a/include/ChangeLog
+++ b/include/ChangeLog
@@ -1,3 +1,13 @@ 
+2024-02-26  Tom Tromey  <tom@tromey.com>
+
+	* gcc-cp-interface.h (gcc_cp_fe_context_function): Update
+	comment.
+	* gcc-c-interface.h (enum gcc_c_api_version) <GCC_C_FE_VERSION_2>:
+	New constant.
+	(gcc_c_fe_context_function): Update comment.
+	* gcc-c-fe.def (finish_record_with_alignment): New method.
+	Update documentation.
+
 2024-01-13  Jakub Jelinek  <jakub@redhat.com>
 
 	* demangle.h (enum demangle_component_type): Add
diff --git a/include/gcc-c-fe.def b/include/gcc-c-fe.def
index 36a765484a7..cb7cf197525 100644
--- a/include/gcc-c-fe.def
+++ b/include/gcc-c-fe.def
@@ -89,7 +89,10 @@  GCC_METHOD5 (int /* bool */, build_add_field,
 
 /* After all the fields have been added to a struct or union, the
    struct or union type must be "finished".  This does some final
-   cleanups in GCC.  */
+   cleanups in GCC.
+
+   Note that when using GCC_C_FE_VERSION_2, it is preferable to call
+   finish_record_with_alignment instead.  */
 
 GCC_METHOD2 (int /* bool */, finish_record_or_union,
 	     gcc_type,			   /* Argument RECORD_OR_UNION_TYPE. */
@@ -220,3 +223,11 @@  GCC_METHOD2 (gcc_type, float_type,
 	     unsigned long,                /* Argument SIZE_IN_BYTES.  */
 	     const char *)		   /* Argument BUILTIN_NAME.  */
 
+/* New in GCC_FE_VERSION_2.  Like finish_record_or_union but the caller also
+   supplies the alignment.  If the alignment is 0, this acts identically to
+   finish_record_or_union.  */
+
+GCC_METHOD3 (int /* bool */, finish_record_with_alignment,
+	     gcc_type,			   /* Argument RECORD_OR_UNION_TYPE. */
+	     unsigned long,		   /* Argument SIZE_IN_BYTES.  */
+	     unsigned long)		   /* Argument ALIGNMENT.  */
diff --git a/include/gcc-c-interface.h b/include/gcc-c-interface.h
index feece1e38a2..700d7483a4a 100644
--- a/include/gcc-c-interface.h
+++ b/include/gcc-c-interface.h
@@ -45,7 +45,10 @@  enum gcc_c_api_version
 
   /* Added char_type.  Added new version of int_type and float_type,
      deprecated int_type_v0 and float_type_v0.  */
-  GCC_C_FE_VERSION_1 = 1
+  GCC_C_FE_VERSION_1 = 1,
+
+  /* Added finish_record_with_alignment method.  */
+  GCC_C_FE_VERSION_2 = 2,
 };
 
 /* Qualifiers.  */
@@ -198,7 +201,11 @@  struct gcc_c_context
 /* The type of the initialization function.  The caller passes in the
    desired base version and desired C-specific version.  If the
    request can be satisfied, a compatible gcc_context object will be
-   returned.  Otherwise, the function returns NULL.  */
+   returned.  In particular, this may return a context object with a higher
+   actual version number than was requested, provided the higher version is
+   fully compatible.  (As of GCC_C_FE_VERSION_2, this is always true.)
+
+   Otherwise, the function returns NULL.  */
 
 typedef struct gcc_c_context *gcc_c_fe_context_function
     (enum gcc_base_api_version,
diff --git a/include/gcc-cp-interface.h b/include/gcc-cp-interface.h
index 2f950729b9b..15b911cb216 100644
--- a/include/gcc-cp-interface.h
+++ b/include/gcc-cp-interface.h
@@ -483,7 +483,11 @@  struct gcc_cp_context
 /* The type of the initialization function.  The caller passes in the
    desired base version and desired C-specific version.  If the
    request can be satisfied, a compatible gcc_context object will be
-   returned.  Otherwise, the function returns NULL.  */
+   returned.  In particular, this may return a context object with a higher
+   actual version number than was requested, provided the higher version is
+   fully compatible.
+
+   Otherwise, the function returns NULL.  */
 
 typedef struct gcc_cp_context *gcc_cp_fe_context_function
     (enum gcc_base_api_version,
diff --git a/libcc1/ChangeLog b/libcc1/ChangeLog
index b4072574ba8..a23130bac15 100644
--- a/libcc1/ChangeLog
+++ b/libcc1/ChangeLog
@@ -1,3 +1,12 @@ 
+2024-02-26  Tom Tromey  <tom@tromey.com>
+
+	PR libcc1/113977
+	* libcc1plugin.cc (plugin_finish_record_or_union): New function.
+	(plugin_finish_record_or_union): Rewrite.
+	(plugin_init): Use GCC_C_FE_VERSION_2.
+	* libcc1.cc (c_vtable): Use GCC_C_FE_VERSION_2.
+	(gcc_c_fe_context): Check for GCC_C_FE_VERSION_2.
+
 2024-02-26  Tom Tromey  <tom@tromey.com>
 
 	* libcp1.cc (libcp1::libcp1): Use FE version number from context.
diff --git a/libcc1/libcc1.cc b/libcc1/libcc1.cc
index 992181e8fdc..1c570f3054d 100644
--- a/libcc1/libcc1.cc
+++ b/libcc1/libcc1.cc
@@ -108,7 +108,7 @@  set_callbacks (struct gcc_c_context *s,
 
 static const struct gcc_c_fe_vtable c_vtable =
 {
-  GCC_C_FE_VERSION_1,
+  GCC_C_FE_VERSION_2,
   set_callbacks,
 
 #define GCC_METHOD0(R, N) \
@@ -165,7 +165,8 @@  gcc_c_fe_context (enum gcc_base_api_version base_version,
 		  enum gcc_c_api_version c_version)
 {
   if ((base_version != GCC_FE_VERSION_0 && base_version != GCC_FE_VERSION_1)
-      || (c_version != GCC_C_FE_VERSION_0 && c_version != GCC_C_FE_VERSION_1))
+      || (c_version != GCC_C_FE_VERSION_0 && c_version != GCC_C_FE_VERSION_1
+	  && c_version != GCC_C_FE_VERSION_2))
     return NULL;
 
   return new libcc1 (&c_vtable);
diff --git a/libcc1/libcc1plugin.cc b/libcc1/libcc1plugin.cc
index f1082d8e9d3..72d17c3b81c 100644
--- a/libcc1/libcc1plugin.cc
+++ b/libcc1/libcc1plugin.cc
@@ -387,9 +387,10 @@  plugin_build_add_field (cc1_plugin::connection *,
 }
 
 int
-plugin_finish_record_or_union (cc1_plugin::connection *,
-			       gcc_type record_or_union_type_in,
-			       unsigned long size_in_bytes)
+plugin_finish_record_with_alignment (cc1_plugin::connection *,
+				     gcc_type record_or_union_type_in,
+				     unsigned long size_in_bytes,
+				     unsigned long align)
 {
   tree record_or_union_type = convert_in (record_or_union_type_in);
 
@@ -407,10 +408,10 @@  plugin_finish_record_or_union (cc1_plugin::connection *,
     }
   else
     {
-      // FIXME there's no way to get this from DWARF,
-      // or even, it seems, a particularly good way to deduce it.
-      SET_TYPE_ALIGN (record_or_union_type,
-		      TYPE_PRECISION (pointer_sized_int_node));
+      if (align == 0)
+	align = TYPE_PRECISION (pointer_sized_int_node);
+
+      SET_TYPE_ALIGN (record_or_union_type, align);
 
       TYPE_SIZE (record_or_union_type) = bitsize_int (size_in_bytes
 						      * BITS_PER_UNIT);
@@ -441,6 +442,15 @@  plugin_finish_record_or_union (cc1_plugin::connection *,
   return 1;
 }
 
+int
+plugin_finish_record_or_union (cc1_plugin::connection *conn,
+			       gcc_type record_or_union_type_in,
+			       unsigned long size_in_bytes)
+{
+  return plugin_finish_record_with_alignment (conn, record_or_union_type_in,
+					      size_in_bytes, 0);
+}
+
 gcc_type
 plugin_build_enum_type (cc1_plugin::connection *self,
 			gcc_type underlying_int_type_in)
@@ -755,7 +765,7 @@  int
 plugin_init (struct plugin_name_args *plugin_info,
 	     struct plugin_gcc_version *)
 {
-  generic_plugin_init (plugin_info, GCC_C_FE_VERSION_1);
+  generic_plugin_init (plugin_info, GCC_C_FE_VERSION_2);
 
   register_callback (plugin_info->base_name, PLUGIN_PRAGMAS,
 		     plugin_init_extra_pragmas, NULL);