]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
gccrs: Handle link_name attribute
authorOwen Avery <powerboat9.gamer@gmail.com>
Sun, 14 Sep 2025 20:57:49 +0000 (16:57 -0400)
committerArthur Cohen <arthur.cohen@embecosm.com>
Thu, 30 Oct 2025 20:30:53 +0000 (21:30 +0100)
gcc/rust/ChangeLog:

* backend/rust-compile-extern.h: Add includes.
(CompileExternItem::visit): Use get_link_name.
(CompileExternItem::get_link_name): New static member function.
* util/rust-attribute-values.h (Attributes::LINK_NAME): New
static constexpr member variable.
* util/rust-attributes.cc (__definitions): New entry for
LINK_NAME.
* util/rust-ggc.cc: Include "rust-ast.h".
(Ident::Ident): Add overload for Rust::Identifier.
* util/rust-ggc.h (class Identifier): Forward declare.
(Ident::Ident): Add overload for Rust::Identifier.

gcc/testsuite/ChangeLog:

* rust/execute/torture/link-name.rs: New test.

Signed-off-by: Owen Avery <powerboat9.gamer@gmail.com>
gcc/rust/backend/rust-compile-extern.h
gcc/rust/util/rust-attribute-values.h
gcc/rust/util/rust-attributes.cc
gcc/rust/util/rust-ggc.cc
gcc/rust/util/rust-ggc.h
gcc/testsuite/rust/execute/torture/link-name.rs [new file with mode: 0644]

index d6aa5899f624bc830e03f52e0f2997969c28619b..a78f9eeeefe2689edebf45976e5aa42aa68af139 100644 (file)
@@ -24,6 +24,8 @@
 #include "rust-compile-type.h"
 #include "rust-diagnostics.h"
 #include "rust-hir-full-decls.h"
+#include "rust-attributes.h"
+#include "rust-attribute-values.h"
 
 namespace Rust {
 namespace Compile {
@@ -57,8 +59,7 @@ public:
     rust_assert (ok);
 
     std::string name = item.get_item_name ().as_string ();
-    // FIXME this is assuming C ABI
-    std::string asm_name = name;
+    GGC::Ident asm_name = get_link_name (item);
 
     tree type = TyTyResolveCompile::compile (ctx, resolved_type);
     bool is_external = true;
@@ -124,16 +125,7 @@ public:
 
     tree compiled_fn_type = TyTyResolveCompile::compile (ctx, fntype);
     std::string ir_symbol_name = function.get_item_name ().as_string ();
-    std::string asm_name = function.get_item_name ().as_string ();
-    if (fntype->get_abi () == ABI::RUST)
-      {
-       // then we need to get the canonical path of it and mangle it
-       auto canonical_path = ctx->get_mappings ().lookup_canonical_path (
-         function.get_mappings ().get_nodeid ());
-
-       ir_symbol_name = canonical_path->get () + fntype->subst_as_string ();
-       asm_name = ctx->mangle_item (fntype, *canonical_path);
-      }
+    GGC::Ident asm_name = get_link_name (function);
 
     const unsigned int flags = Backend::function_is_declaration;
     tree fndecl = Backend::function (compiled_fn_type, ir_symbol_name, asm_name,
@@ -158,6 +150,36 @@ private:
       ref_locus (ref_locus)
   {}
 
+  template <typename T> static GGC::Ident get_link_name (T &obj)
+  {
+    AST::Attribute *use_attr = nullptr;
+
+    for (auto &attr : obj.get_outer_attrs ())
+      {
+       if (attr.get_path ().as_string () == Values::Attributes::LINK_NAME)
+         {
+           // later attributes override earlier ones
+           // TODO: add warning -- should duplicate
+           //       attributes be folded elsewhere?
+           use_attr = &attr;
+         }
+      }
+
+    if (use_attr)
+      {
+       auto link_name
+         = Analysis::Attributes::extract_string_literal (*use_attr);
+
+       if (!link_name.has_value ())
+         rust_error_at (use_attr->get_locus (),
+                        "malformed %<link_name%> attribute input");
+       else
+         return *link_name;
+      }
+
+    return obj.get_item_name ();
+  }
+
   TyTy::BaseType *concrete;
   tree reference;
   location_t ref_locus;
index 3b09e8493d18938e4ff5596f5626b96fb57be0f9..0f35f56f798e6e01a350cedb97dde70f47050b7b 100644 (file)
@@ -36,6 +36,7 @@ public:
   static constexpr auto &DOC = "doc";
   static constexpr auto &MUST_USE = "must_use";
   static constexpr auto &LANG = "lang";
+  static constexpr auto &LINK_NAME = "link_name";
   static constexpr auto &LINK_SECTION = "link_section";
   static constexpr auto &NO_MANGLE = "no_mangle";
   static constexpr auto &REPR = "repr";
index 716af3af699a21be371dd249db527c6e2f7c9d97..bd91fdd5d031b0f52ec25e6e97a4b8c697669c8e 100644 (file)
@@ -78,6 +78,7 @@ static const BuiltinAttrDefinition __definitions[]
      {Attrs::DOC, HIR_LOWERING},
      {Attrs::MUST_USE, STATIC_ANALYSIS},
      {Attrs::LANG, HIR_LOWERING},
+     {Attrs::LINK_NAME, CODE_GENERATION},
      {Attrs::LINK_SECTION, CODE_GENERATION},
      {Attrs::NO_MANGLE, CODE_GENERATION},
      {Attrs::REPR, CODE_GENERATION},
index 0722af2b7188a8b7cc0c52761fecbc0420150748..46220a2acd80b55d6e514acd9917a799008700c4 100644 (file)
@@ -17,6 +17,7 @@
 // <http://www.gnu.org/licenses/>.
 
 #include "rust-ggc.h"
+#include "rust-ast.h"
 #include "stringpool.h"
 
 namespace Rust {
@@ -29,6 +30,8 @@ Ident::Ident (const std::string &str)
   : inner (get_identifier_with_length (str.c_str (), str.length ()))
 {}
 
+Ident::Ident (const Rust::Identifier &ident) : Ident (ident.as_string ()) {}
+
 bool
 Ident::operator== (const std::string &other) const
 {
index da28edeffe0b99c19b94a8289d238908b3e2925d..da4ede1598501b4c2e5367149c77b24ced2c0c18 100644 (file)
@@ -24,6 +24,9 @@
 
 namespace Rust {
 
+// forward declare
+class Identifier;
+
 namespace GGC {
 
 class Ident
@@ -33,6 +36,7 @@ class Ident
 public:
   Ident (const char *str);
   Ident (const std::string &str);
+  Ident (const Rust::Identifier &ident);
 
   bool operator== (const Ident &other) const { return inner == other.inner; }
   bool operator== (const std::string &other) const;
diff --git a/gcc/testsuite/rust/execute/torture/link-name.rs b/gcc/testsuite/rust/execute/torture/link-name.rs
new file mode 100644 (file)
index 0000000..1ab1ac1
--- /dev/null
@@ -0,0 +1,16 @@
+// { dg-additional-options "-fdump-rtl-final" }
+// { dg-final { scan-rtl-dump "printf" "final" } }
+// { dg-output "gcc\r*\n" }
+
+extern "C" {
+    #[link_name = "printf"]
+    fn druckt(fmt: *const i8, ...);
+}
+
+fn main() -> i32 {
+    let a = "gcc\0";
+
+    unsafe { druckt("%s\n\0" as *const str as *const i8, a as *const str as *const i8); }
+
+    0
+}