From: Pierre-Emmanuel Patry <[email protected]>

The rust language requires the export_name attribute to change the name
of a symbol within the assembly whilst keeping a different name at the
language level. This is used multiple times within rust-for-linux.

gcc/rust/ChangeLog:

        * backend/rust-compile-base.cc: Change the assembly name on functions
        with the export_name attribute. Do not mangle the name.
        * util/rust-attribute-values.h: Add export_name attribute value.
        * util/rust-attributes.cc: Add export_name attribute to builtin
        attribute list.

gcc/testsuite/ChangeLog:

        * rust/compile/export_name.rs: New test.

Signed-off-by: Pierre-Emmanuel Patry <[email protected]>
---
This change was merged into the gccrs repository and is posted here for
upstream visibility and potential drive-by review, as requested by GCC
release managers.
Each commit email contains a link to its details on github from where you can
find the Pull-Request and associated discussions.


Commit on github: 
https://github.com/Rust-GCC/gccrs/commit/2d92c493f5a4518d07cfe7120704ef449f108684

The commit has been mentioned in the following pull-request(s):
 - https://github.com/Rust-GCC/gccrs/pull/4385

 gcc/rust/backend/rust-compile-base.cc     | 26 ++++++++++++++++++++---
 gcc/rust/util/rust-attribute-values.h     |  1 +
 gcc/rust/util/rust-attributes.cc          |  1 +
 gcc/testsuite/rust/compile/export_name.rs |  7 ++++++
 4 files changed, 32 insertions(+), 3 deletions(-)
 create mode 100644 gcc/testsuite/rust/compile/export_name.rs

diff --git a/gcc/rust/backend/rust-compile-base.cc 
b/gcc/rust/backend/rust-compile-base.cc
index 4d9fb00c0..655a43ac9 100644
--- a/gcc/rust/backend/rust-compile-base.cc
+++ b/gcc/rust/backend/rust-compile-base.cc
@@ -702,18 +702,38 @@ HIRCompileBase::compile_function (
       /* So that 'MAIN_NAME_P' works.  */
       main_identifier_node = get_identifier (ir_symbol_name.c_str ());
     }
+  // Local name because fn_name is not mutable.
   std::string asm_name = fn_name;
 
+  // conditionally mangle the function name
+  bool should_mangle = true;
+
+  auto get_export_name = [] (AST::Attribute &attr) {
+    return attr.get_path ().as_string () == Values::Attributes::EXPORT_NAME;
+  };
+  auto export_name_attr
+    = std::find_if (outer_attrs.begin (), outer_attrs.end (), get_export_name);
+
+  tl::optional<std::string> backend_asm_name = tl::nullopt;
+
+  if (export_name_attr != outer_attrs.end ())
+    {
+      asm_name
+       = Analysis::Attributes::extract_string_literal (*export_name_attr)
+           .value (); // Checked within attribute checker
+      backend_asm_name = asm_name;
+      should_mangle = false;
+    }
+
   unsigned int flags = 0;
   tree fndecl = Backend::function (compiled_fn_type, ir_symbol_name,
-                                  tl::nullopt /* asm_name */, flags, locus);
+                                  backend_asm_name, flags, locus);
 
   setup_fndecl (fndecl, is_main_fn, fntype->has_substitutions_defined (),
                visibility, qualifiers, outer_attrs);
   setup_abi_options (fndecl, get_abi (outer_attrs, qualifiers));
 
-  // conditionally mangle the function name
-  bool should_mangle = should_mangle_item (fndecl);
+  should_mangle &= should_mangle_item (fndecl);
   if (!is_main_fn && should_mangle)
     asm_name = ctx->mangle_item (fntype, canonical_path);
   SET_DECL_ASSEMBLER_NAME (fndecl,
diff --git a/gcc/rust/util/rust-attribute-values.h 
b/gcc/rust/util/rust-attribute-values.h
index 3bba0c859..45a81e441 100644
--- a/gcc/rust/util/rust-attribute-values.h
+++ b/gcc/rust/util/rust-attribute-values.h
@@ -39,6 +39,7 @@ public:
   static constexpr auto &LINK_NAME = "link_name";
   static constexpr auto &LINK_SECTION = "link_section";
   static constexpr auto &NO_MANGLE = "no_mangle";
+  static constexpr auto &EXPORT_NAME = "export_name";
   static constexpr auto &REPR = "repr";
   static constexpr auto &RUSTC_BUILTIN_MACRO = "rustc_builtin_macro";
   static constexpr auto &RUSTC_MACRO_TRANSPARENCY = "rustc_macro_transparency";
diff --git a/gcc/rust/util/rust-attributes.cc b/gcc/rust/util/rust-attributes.cc
index a58336ef9..1ab6564dc 100644
--- a/gcc/rust/util/rust-attributes.cc
+++ b/gcc/rust/util/rust-attributes.cc
@@ -81,6 +81,7 @@ static const BuiltinAttrDefinition __definitions[]
      {Attrs::LINK_NAME, CODE_GENERATION},
      {Attrs::LINK_SECTION, CODE_GENERATION},
      {Attrs::NO_MANGLE, CODE_GENERATION},
+     {Attrs::EXPORT_NAME, CODE_GENERATION},
      {Attrs::REPR, CODE_GENERATION},
      {Attrs::RUSTC_BUILTIN_MACRO, EXPANSION},
      {Attrs::RUSTC_MACRO_TRANSPARENCY, EXPANSION},
diff --git a/gcc/testsuite/rust/compile/export_name.rs 
b/gcc/testsuite/rust/compile/export_name.rs
new file mode 100644
index 000000000..4d8abcdd5
--- /dev/null
+++ b/gcc/testsuite/rust/compile/export_name.rs
@@ -0,0 +1,7 @@
+#[export_name = "other_name"]
+fn func() {}
+// { dg-final { scan-assembler "other_name" } }
+
+fn main() {
+    func();
+}

base-commit: 4d60acdace07b0cbed73a86a17e14bca6bef67cd
-- 
2.52.0

Reply via email to